{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Title: #Check if Array Is Sorted and Rotated"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Difficulty: #Easy"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Category Title: #Algorithms"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Tag Slug: #array"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Name Translated: #数组"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Solution Name: check"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Translated Title: #检查数组是否经排序和轮转得到"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Translated Content:\n",
    "<p>给你一个数组 <code>nums</code> 。<code>nums</code> 的源数组中，所有元素与 <code>nums</code> 相同，但按非递减顺序排列。</p>\n",
    "\n",
    "<p>如果&nbsp;<code>nums</code> 能够由源数组轮转若干位置（包括 0 个位置）得到，则返回 <code>true</code><em> </em>；否则，返回 <code>false</code> 。</p>\n",
    "\n",
    "<p>源数组中可能存在 <strong>重复项</strong> 。</p>\n",
    "\n",
    "<p><strong>注意：</strong>我们称数组 <code>A</code> 在轮转 <code>x</code> 个位置后得到长度相同的数组 <code>B</code> ，当它们满足 <code>A[i] == B[(i+x) % A.length]</code> ，其中 <code>%</code> 为取余运算。</p>\n",
    "\n",
    "<p>&nbsp;</p>\n",
    "\n",
    "<p><strong>示例 1：</strong></p>\n",
    "\n",
    "<pre>\n",
    "<strong>输入：</strong>nums = [3,4,5,1,2]\n",
    "<strong>输出：</strong>true\n",
    "<strong>解释：</strong>[1,2,3,4,5] 为有序的源数组。\n",
    "可以轮转 x = 3 个位置，使新数组从值为 3 的元素开始：[3,4,5,1,2] 。\n",
    "</pre>\n",
    "\n",
    "<p><strong>示例 2：</strong></p>\n",
    "\n",
    "<pre>\n",
    "<strong>输入：</strong>nums = [2,1,3,4]\n",
    "<strong>输出：</strong>false\n",
    "<strong>解释：</strong>源数组无法经轮转得到 nums 。\n",
    "</pre>\n",
    "\n",
    "<p><strong>示例 3：</strong></p>\n",
    "\n",
    "<pre>\n",
    "<strong>输入：</strong>nums = [1,2,3]\n",
    "<strong>输出：</strong>true\n",
    "<strong>解释：</strong>[1,2,3] 为有序的源数组。\n",
    "可以轮转 x = 0 个位置（即不轮转）得到 nums 。\n",
    "</pre>\n",
    "\n",
    "<p>&nbsp;</p>\n",
    "\n",
    "<p><strong>提示：</strong></p>\n",
    "\n",
    "<ul>\n",
    "\t<li><code>1 &lt;= nums.length &lt;= 100</code></li>\n",
    "\t<li><code>1 &lt;= nums[i] &lt;= 100</code></li>\n",
    "</ul>\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Description: [check-if-array-is-sorted-and-rotated](https://leetcode.cn/problems/check-if-array-is-sorted-and-rotated/description/)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Solutions: [check-if-array-is-sorted-and-rotated](https://leetcode.cn/problems/check-if-array-is-sorted-and-rotated/solutions/)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "test_cases = ['[3,4,5,1,2]', '[2,1,3,4]', '[1,2,3]']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "\n",
    "    def restoreIpAddresses(self, s: str):\n",
    "        self.res = []\n",
    "        self.tmp = []\n",
    "        self.dfs(s, 4)\n",
    "        return self.res\n",
    "\n",
    "    def dfs(self, s, deep):\n",
    "        if deep <= 0 and len(s) > 0:\n",
    "            return None\n",
    "        if deep > len(s):\n",
    "            return None\n",
    "        if deep == len(s):\n",
    "            for c in s:\n",
    "                self.tmp.append(c)\n",
    "            self.res.append(\".\".join(self.tmp))\n",
    "            for c in s:\n",
    "                self.tmp.pop()\n",
    "        else:\n",
    "            for i in range(1, min(4, len(s)+1)):\n",
    "                if self.check(s[:i]):\n",
    "                    self.tmp.append(s[:i])\n",
    "                    self.dfs(s[i:], deep-1)\n",
    "                    self.tmp.pop()\n",
    "        return None\n",
    "\n",
    "    def check(self, s):\n",
    "        if len(s) == 0:\n",
    "            return False\n",
    "        a = int(s)\n",
    "        if (a == 0 and len(s) > 1) or str(a)!=s:\n",
    "            return False\n",
    "        if a > 255:\n",
    "            return False\n",
    "        return True\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def restoreIpAddresses(self, s: str) -> List[str]:\n",
    "        def check(i,j):\n",
    "            if s[i]==\"0\" and i!=j:\n",
    "                return False\n",
    "            return 0<=int(s[i:j+1])<=255\n",
    "        def dfs(i):\n",
    "            if i>=n and len(path)==4:\n",
    "                res.append(\".\".join(path))\n",
    "                return\n",
    "            if i>=n or len(path)>=4:\n",
    "                return\n",
    "            for j in range(i,min(i+3,n)):\n",
    "                if check(i,j):\n",
    "                    path.append(s[i:j+1])\n",
    "                    dfs(j+1)\n",
    "                    path.pop()\n",
    "        n = len(s)\n",
    "        res = []\n",
    "        path = []\n",
    "        dfs(0)\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def restoreIpAddresses(self, s: str) -> List[str]:\n",
    "        def check(i,j):\n",
    "            if s[i]==\"0\" and i!=j:\n",
    "                return False\n",
    "            return 0<=int(s[i:j+1])<=255\n",
    "        def dfs(index, n, path):\n",
    "            if index>=n and len(path)==4:\n",
    "                res.append(\".\".join(path))\n",
    "                return\n",
    "            if index>=n or len(path)>=4:\n",
    "                return\n",
    "            for j in range(index,min(index+3,n)):\n",
    "                if check(index,j):\n",
    "                    path.append(s[index:j+1])\n",
    "                    dfs(j+1,n,path)\n",
    "                    path.pop()\n",
    "        n = len(s)\n",
    "        res = []\n",
    "    \n",
    "        dfs(0,n,[])\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def restoreIpAddresses(self, s: str) -> List[str]:\n",
    "        self.res = []\n",
    "        if len(s)>12 or len(s)<4:return []\n",
    "        def check(s):\n",
    "            if len(s)<=0 or len(s)>3:return False\n",
    "            if s[0]=='0' and len(s)>1:return False\n",
    "            if eval(s)<0 or eval(s)>255:return False\n",
    "            return True\n",
    "\n",
    "        def dfs(loc):\n",
    "            if len(loc)==3:\n",
    "                if check(s[loc[-1]+1:]):\n",
    "                    self.res.append(s[:loc[0]+1]+'.'+s[loc[0]+1:loc[1]+1]+'.'+s[loc[1]+1:loc[2]+1]+'.'+s[loc[2]+1:])\n",
    "                return \n",
    "            if len(loc)>0:\n",
    "                for i in range(1+loc[-1],len(s)):\n",
    "                    if check(s[loc[-1]+1:i+1]):dfs(loc+[i])\n",
    "            else:\n",
    "                for i in range(len(s)):\n",
    "                    if check(s[:i+1]):dfs(loc+[i])\n",
    "        dfs([])\n",
    "        return self.res   \n",
    "                    \n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def restoreIpAddresses(self, s: str) -> List[str]:\n",
    "        n = len(s)\n",
    "        ips = []\n",
    "        if n < 4 or n > 12:\n",
    "            return ips\n",
    "        for i1 in range(min(4, n)):\n",
    "            seg1 = s[:i1 + 1]\n",
    "            if not self.check_ip(seg1):\n",
    "                continue\n",
    "            for i2 in range(i1 + 1, min(i1 + 4, n)):\n",
    "                seg2 = s[i1 + 1:i2 + 1]\n",
    "                if not self.check_ip(seg2):\n",
    "                    continue\n",
    "                for i3 in range(i2 + 1, min(i2 + 4, n)):\n",
    "                    seg3 = s[i2 + 1:i3 + 1]\n",
    "                    seg4 = s[i3 + 1:]\n",
    "                    if self.check_ip(seg3) and self.check_ip(seg4):\n",
    "                        ips.append(seg1 + \".\" + seg2 + \".\" + seg3 + \".\" + seg4)\n",
    "        return ips\n",
    "\n",
    "    def check_ip(self, s: str) -> bool:\n",
    "        n = len(s)\n",
    "        if n == 0 or n > 3:\n",
    "            return False\n",
    "        if s[0] == \"0\" and n > 1:\n",
    "            return False\n",
    "        int_val = int(s)\n",
    "        return int_val >= 0 and int_val <= 255"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def restoreIpAddresses(self, s: str) -> List[str]:\n",
    "        if len(s) > 12 or len(s) < 4:\n",
    "            return []\n",
    "        res = []\n",
    "        # 隔板法，枚举三个隔板位置\n",
    "        for i in range(1, len(s) - 2):\n",
    "            for j in range(i+1, len(s) - 1):\n",
    "                for k in range(j+1, len(s)):\n",
    "                    if self.checked(s, i, j, k):\n",
    "                        ans = f\"{int(s[0:i])}.{int(s[i:j])}.{int(s[j:k])}.{int(s[k:])}\"\n",
    "                        res.append(ans)\n",
    "        return res\n",
    "    \n",
    "    def checked(self,s, i, j, k):\n",
    "        str1 = s[0:i]\n",
    "        if(len(str1) > 1 and str1[0] == '0') or int(str1) > 255:\n",
    "            return False\n",
    "        \n",
    "        str2 = s[i:j]\n",
    "        if(len(str2) > 1 and str2[0] == \"0\") or int(str2) > 255:\n",
    "            return False\n",
    "\n",
    "        str3 = s[j:k]\n",
    "        if(len(str3) > 1 and str3[0] == \"0\") or int(str3) > 255:\n",
    "            return False\n",
    "        \n",
    "        str4 = s[k:]\n",
    "        if(len(str4) > 1 and str4[0] == \"0\") or int(str4) > 255:\n",
    "            return False\n",
    "        return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def restoreIpAddresses(self, s: str) -> List[str]:\n",
    "        start = 0\n",
    "        end = 0\n",
    "        res = []\n",
    "        for i in range(0,3):\n",
    "            for j in range(i+1,min(len(s),i+4)):\n",
    "                for k in range(j+1,min(len(s),j+4)):\n",
    "                    if k+4 >= len(s) and k+1 < len(s) and self.check(s[0:i+1]) and self.check(s[i+1:j+1]) and self.check(s[j+1:k+1]) and self.check(s[k+1:]):\n",
    "                        res.append(s[0:i+1] + '.' + s[i+1:j+1] + '.' + s[j+1:k+1] + '.' + s[k+1:])\n",
    "                        print(res)\n",
    "        return res\n",
    "\n",
    "\n",
    "    def check(self,s):\n",
    "        res = 0\n",
    "        if len(s)>1 and s[0] == '0':\n",
    "            return False\n",
    "        res = int(s)\n",
    "        if res>=0 and res <= 255:\n",
    "            return True\n",
    "        return False\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def restoreIpAddresses(self, s: str) -> List[str]:\n",
    "        res = []\n",
    "        def check(s):\n",
    "            if len(s) <= 0:\n",
    "                return False\n",
    "            if s != '0' and s[0] == '0':\n",
    "                return False\n",
    "            elif int(s) > 255 or int(s) < 0:\n",
    "                return False\n",
    "            else:\n",
    "                return True\n",
    "        \n",
    "        def dfs(index,path):\n",
    "            if len(path) >= 3:\n",
    "                if check(s[index:]):\n",
    "                    path.append(s[index:])\n",
    "                    res.append(path.copy())\n",
    "                    path.pop()\n",
    "                return\n",
    "\n",
    "            for i in range(1,4):\n",
    "                if check(s[index:index+i]):\n",
    "                    path.append(s[index:index+i])\n",
    "                    dfs(index+i,path)\n",
    "                    path.pop()\n",
    "        \n",
    "        dfs(0, [])\n",
    "        res1 = []\n",
    "        for rs in res:\n",
    "            tp = ''\n",
    "            for si in rs:\n",
    "                tp += si\n",
    "                tp += '.'\n",
    "            res1.append(tp[:-1])\n",
    "        return res1\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def restoreIpAddresses(self, s: str) -> List[str]:\n",
    "        N = len(s) \n",
    "        if N < 4 or N > 12: \n",
    "            return [] \n",
    "        ans = [] \n",
    "        cur = [] \n",
    "        @cache \n",
    "        def check(d): \n",
    "            leng = len(d) \n",
    "            val = int(d) \n",
    "            if leng < 1 or leng > 3 or (leng==2 and val<10) or (leng==3 and (val<100 or val>255)): \n",
    "                return False \n",
    "            return True \n",
    "\n",
    "        def dfs(i: int ):  \n",
    "            if len(cur) == 3:                   # 已得到ip前3个数\n",
    "                if i<N and check(s[i:]):        # 判断第四个数是否合法\n",
    "                    cur.append(s[i:]) \n",
    "                    ans.append('.'.join(cur)) \n",
    "                    cur.pop() \n",
    "                return \n",
    "            for k in range(3): \n",
    "                if i+k<N and check(s[i:i+k+1]): # 检查当前位置的1,2,3位组合\n",
    "                    cur.append(s[i:i+k+1]) \n",
    "                    dfs(i+k+1) \n",
    "                    cur.pop() \n",
    "        dfs(0) \n",
    "        return ans "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def restoreIpAddresses(self, s: str) -> List[str]:\n",
    "        self.res = []\n",
    "        if len(s)>12 or len(s)<4:return []\n",
    "        def check(s):\n",
    "            if len(s)<=0 or len(s)>3:return False\n",
    "            if s[0]=='0' and len(s)>1:return False\n",
    "            if eval(s)<0 or eval(s)>255:return False\n",
    "            return True\n",
    "        @lru_cache\n",
    "        def dfs(loc):\n",
    "            if loc[0]!=-1 and loc[1]!=-1 and loc[2]!=-1:\n",
    "                if check(s[loc[-1]+1:]):\n",
    "                    self.res.append(s[:loc[0]+1]+'.'+s[loc[0]+1:loc[1]+1]+'.'+s[loc[1]+1:loc[2]+1]+'.'+s[loc[2]+1:])\n",
    "                return \n",
    "            if loc[0]==-1:\n",
    "                for i in range(len(s)):\n",
    "                    if check(s[:i+1]):dfs((i,-1,-1))\n",
    "            elif loc[1]==-1:\n",
    "                for i in range(loc[0]+1,len(s)):\n",
    "                    if check(s[loc[0]+1:i+1]):dfs((loc[0],i,-1))\n",
    "            else:\n",
    "                for i in range(loc[1]+1,len(s)):\n",
    "                    if check(s[loc[1]+1:i+1]):dfs((loc[0],loc[1],i))\n",
    "        dfs((-1,-1,-1))\n",
    "        return self.res   \n",
    "                    \n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "from typing import List\n",
    "\n",
    "class Solution:\n",
    "    def restoreIpAddresses(self, s: str) -> List[str]:\n",
    "        def backtrack(start=0, parts=[]):\n",
    "            # Base case: if we have 4 parts and have used all characters in the string\n",
    "            if len(parts) == 4 and start == len(s):\n",
    "                result.append(\".\".join(parts))\n",
    "                return\n",
    "            \n",
    "            # If we already have 4 parts but still have characters left in the string, stop\n",
    "            if len(parts) == 4:\n",
    "                return\n",
    "            \n",
    "            for end in range(start + 1, len(s) + 1):\n",
    "                # Extract the current part from the string and validate it\n",
    "                part = s[start:end]\n",
    "                \n",
    "                if len(part) > 1 and part[0] == '0':  # Eliminate parts with leading zeros\n",
    "                    return\n",
    "                \n",
    "                if 0 <= int(part) <= 255:  # Check if it's a valid segment\n",
    "                    backtrack(end, parts + [part])\n",
    "                else:  # No need to check further as it will only create invalid segments\n",
    "                    break\n",
    "        \n",
    "        result = []\n",
    "        backtrack()\n",
    "        return result\n",
    "\n",
    "# Test the function\n",
    "sol = Solution()\n",
    "print(sol.restoreIpAddresses(\"25525511135\"))\n",
    "print(sol.restoreIpAddresses(\"0000\"))\n",
    "print(sol.restoreIpAddresses(\"010010\"))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Data:\n",
    "    def __init__(self, idx, height):\n",
    "        self.idx = idx\n",
    "        self.height = height\n",
    "\n",
    "class Stack:\n",
    "    def __init__(self):\n",
    "        self.data = []\n",
    "        self.end_idx = -1\n",
    "\n",
    "    def clean(self):\n",
    "        self.data = []\n",
    "        self.end_idx = -1\n",
    "\n",
    "    def pop(self):\n",
    "        if self.end_idx >= 0:\n",
    "            self.end_idx = self.end_idx - 1\n",
    "            return self.data[self.end_idx + 1]\n",
    "        else:\n",
    "            return None\n",
    "        \n",
    "    def push(self, data):\n",
    "        self.end_idx = self.end_idx + 1\n",
    "        if len(self.data) - 1 >= self.end_idx:\n",
    "            self.data[self.end_idx] = data\n",
    "        else:\n",
    "            self.data.append(data)\n",
    "\n",
    "    def top(self):\n",
    "        if self.end_idx >= 0:\n",
    "            return self.data[self.end_idx]\n",
    "        else:\n",
    "            return None\n",
    "\n",
    "    def size(self):\n",
    "        return self.end_idx + 1\n",
    "\n",
    "\n",
    "def check(ss, idx, h):\n",
    "    if ss.size() == 0:\n",
    "        ss.push(Data(idx, h))\n",
    "        return ss, -1\n",
    "    elif ss.top().height < h:\n",
    "        out_idx = ss.top().idx\n",
    "        ss.push(Data(idx, h))\n",
    "        return ss, out_idx\n",
    "    else:\n",
    "        ss.pop()\n",
    "        return check(ss, idx, h)\n",
    "    \n",
    "\n",
    "\n",
    "class Solution:\n",
    "    def largestRectangleArea(self, heights: List[int]) -> int:\n",
    "\n",
    "        ss = Stack()\n",
    "        left = [-1 for i in range(len(heights))]\n",
    "        for i in range(len(heights)):\n",
    "            ss, left[i] = check(ss, i, heights[i])\n",
    "            # for ii in range(ss.end_idx):\n",
    "            #     print(ss.data[ii].height, ss.data[ii].idx)\n",
    "            # print()\n",
    "        \n",
    "        ss = Stack()\n",
    "        right = [-1 for i in range(len(heights))]\n",
    "        for i in range(len(heights)-1, -1, -1):\n",
    "            ss, right[i] = check(ss, i, heights[i])\n",
    "            if right[i] < 0:\n",
    "                right[i] = len(heights)\n",
    "\n",
    "        area = [heights[i] * (right[i] - left[i] - 1) for i in range(len(heights))]\n",
    "\n",
    "        max_area = 0\n",
    "        for i in range(len(heights)):\n",
    "            max_area = max(max_area, area[i])\n",
    "\n",
    "        # print(left)\n",
    "        # print(right)\n",
    "        # print(area)\n",
    "\n",
    "        return max_area\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minSubArrayLen(self, target: int, nums: List[int]) -> int:\n",
    "        n=len(nums)\n",
    "        if sum(nums)<target:\n",
    "            return 0\n",
    "        cur=0\n",
    "        presum=[0]\n",
    "        for i in range(n):\n",
    "            cur+=nums[i]\n",
    "            presum.append(cur)\n",
    "        cmin=1\n",
    "        cmax=n\n",
    "        def check(mid):\n",
    "            e=[presum[i+mid]-presum[i] for i in range(n-mid+1)]\n",
    "            return max(e)>=target\n",
    "        while cmin<=cmax:\n",
    "            mid=(cmin+cmax)//2\n",
    "            if check(mid):\n",
    "                cur=mid\n",
    "                cmax=mid-1\n",
    "            else:\n",
    "                cmin=mid+1\n",
    "        return cur"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def unSuitability(self, operate: List[int]) -> int:\n",
    "        low, high = 0, 2004\n",
    "        \n",
    "        def check(m: int) -> bool:\n",
    "            m = m + 1\n",
    "            store = [True] * m\n",
    "            comp = [False] * m\n",
    "            \n",
    "            for o in operate:\n",
    "                for i in range(m):\n",
    "                    c1 = (i+o) < m and store[i+o]\n",
    "                    c2 = (i-o) >= 0 and store[i-o]\n",
    "                    comp[i] = c1 or c2\n",
    "                store, comp = comp, store\n",
    "            \n",
    "            return any(store[:m])\n",
    "        \n",
    "        while high > low:\n",
    "            mid = (high + low) // 2\n",
    "            if check(mid): high = mid\n",
    "            else: low = mid + 1\n",
    "        \n",
    "        return low"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def unSuitability(self, operate: List[int]) -> int:\n",
    "        low, high = 0, max(operate) * 2\n",
    "        \n",
    "        def check(m: int) -> bool:\n",
    "            m = m + 1\n",
    "            store = [True] * m\n",
    "            comp = [False] * m\n",
    "            \n",
    "            for o in operate:\n",
    "                for i in range(m):\n",
    "                    c1 = (i+o) < m and store[i+o]\n",
    "                    c2 = (i-o) >= 0 and store[i-o]\n",
    "                    comp[i] = c1 or c2\n",
    "                store, comp = comp, store\n",
    "            \n",
    "            return any(store[:m])\n",
    "        \n",
    "        while high > low:\n",
    "            mid = (high + low) // 2\n",
    "            if check(mid): high = mid\n",
    "            else: low = mid + 1\n",
    "        \n",
    "        return low"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def unSuitability(self, nums: List[int]) -> int:\n",
    "        # https://codeforces.com/contest/1579/submission/130462038\n",
    "        # 二分答案\n",
    "        # 对于答案 mid, 存在一系列操作, 极差<=mid?\n",
    "        # 起点0, 低点min,高点max\n",
    "        # 现在进行平移: 低点0, 高点mid,起始点为 z [0,mid]\n",
    "        # 问题转化为: 是否存在起始点为 z , 且一系列操作都不超出[0,mid]的方案\n",
    "        # 设当前起始点集合为 [0,mid] 的所有数,共 mid+1个数\n",
    "        # 对于较大的数z,下一步可以 减去nums[i],来保证在区间\n",
    "        # 对于较小的数z,下一步可以 加上nums[i],来保证在区间\n",
    "        # 对于中间的数z,下一步可以 加减nums[i],可能都超出区间\n",
    "        # 如果存在z, 从起点到终点都有不超出[0,mid]的方案, 则答案有效\n",
    "        def cando(x):\n",
    "            s=(1<<(x+1))-1\n",
    "            rest = s\n",
    "            for c in nums:\n",
    "                s1 = (rest>>c) & s\n",
    "                s2 = (rest<<c) & s\n",
    "                rest=s1|s2 \n",
    "            return rest\n",
    "        # 假设起点为0,下一步的范围即为[-maxnum,maxnum]\n",
    "        # 假设起点< 0,下一步的范围即为[起点,maxnum-abs(起点)]\n",
    "        # 假设起点> 0,下一步的范围即为[-maxnum+abs(起点),起点]\n",
    "        l,r = 1, max(nums)<<1\n",
    "        while l<=r:\n",
    "            x=l+(r-l)//2\n",
    "            if cando(x):\n",
    "                r=x-1\n",
    "            else:\n",
    "                l=x+1\n",
    "        return l\n",
    "    def unSuitability_1(self, nums: List[int]) -> int:\n",
    "        def check(mid: int) -> bool:\n",
    "            mask = (1 << (mid + 1)) - 1\n",
    "            dp = mask\n",
    "            for num in nums:\n",
    "                dp = ((dp << num) | (dp >> num)) & mask\n",
    "            return dp != 0\n",
    "\n",
    "        left, right = 0, sum(nums)  # 实际的上界为 max(nums)*2\n",
    "        while left <= right:\n",
    "            mid = (left + right) // 2\n",
    "            if check(mid):\n",
    "                right = mid - 1\n",
    "            else:\n",
    "                left = mid + 1\n",
    "        return left"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def unSuitability(self, nums: List[int]) -> int:\n",
    "        # 使用状态压缩动态规划检查是否存在一个有效的操作序列\n",
    "        def cando(x):\n",
    "            s=(1<<(x+1))-1\n",
    "            rest = s\n",
    "            for c in nums:\n",
    "                s1 = (rest>>c) & s\n",
    "                s2 = (rest<<c) & s\n",
    "                rest=s1|s2 \n",
    "            return rest\n",
    "        \n",
    "        # 二分查找确定最小的不适宜度\n",
    "        l,r = 1, max(nums)<<1\n",
    "        while l<=r:\n",
    "            x=l+(r-l)//2\n",
    "            if cando(x):\n",
    "                r=x-1\n",
    "            else:\n",
    "                l=x+1\n",
    "        return l\n",
    "    \n",
    "    def unSuitability_1(self, nums: List[int]) -> int:\n",
    "        # 另一种状态压缩动态规划的实现\n",
    "        def check(mid: int) -> bool:\n",
    "            mask = (1 << (mid + 1)) - 1\n",
    "            dp = mask\n",
    "            for num in nums:\n",
    "                dp = ((dp << num) | (dp >> num)) & mask\n",
    "            return dp != 0\n",
    "\n",
    "        left, right = 0, sum(nums)  # 实际的上界为 max(nums)*2\n",
    "        while left <= right:\n",
    "            mid = (left + right) // 2\n",
    "            if check(mid):\n",
    "                right = mid - 1\n",
    "            else:\n",
    "                left = mid + 1\n",
    "        return left\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "\n",
    "class Solution:\n",
    "    def unSuitability(self, nums: List[int]) -> int:\n",
    "        # https://codeforces.com/contest/1579/submission/130462038\n",
    "        # 二分答案\n",
    "        # 对于答案 mid, 存在一系列操作, 极差<=mid?\n",
    "        # 起点0, 低点min,高点max\n",
    "        # 现在进行平移: 低点0, 高点mid,起始点为 z [0,mid]\n",
    "        # 问题转化为: 是否存在起始点为 z , 且一系列操作都不超出[0,mid]的方案\n",
    "        # 设当前起始点集合为 [0,mid] 的所有数,共 mid+1个数\n",
    "        # 对于较大的数z,下一步可以 减去nums[i],来保证在区间\n",
    "        # 对于较小的数z,下一步可以 加上nums[i],来保证在区间\n",
    "        # 对于中间的数z,下一步可以 加减nums[i],可能都超出区间\n",
    "        # 如果存在z, 从起点到终点都有不超出[0,mid]的方案, 则答案有效\n",
    "        def cando(x):\n",
    "            s=(1<<(x+1))-1\n",
    "            rest = s\n",
    "            for c in nums:\n",
    "                s1 = (rest>>c) & s\n",
    "                s2 = (rest<<c) & s\n",
    "                rest=s1|s2 \n",
    "            return rest\n",
    "        # 假设起点为0,下一步的范围即为[-maxnum,maxnum]\n",
    "        # 假设起点< 0,下一步的范围即为[起点,maxnum-abs(起点)]\n",
    "        # 假设起点> 0,下一步的范围即为[-maxnum+abs(起点),起点]\n",
    "        l,r = 1, max(nums)<<1\n",
    "        while l<=r:\n",
    "            x=l+(r-l)//2\n",
    "            if cando(x):\n",
    "                r=x-1\n",
    "            else:\n",
    "                l=x+1\n",
    "        return l\n",
    "    def unSuitability_1(self, nums: List[int]) -> int:\n",
    "        def check(mid: int) -> bool:\n",
    "            mask = (1 << (mid + 1)) - 1\n",
    "            dp = mask\n",
    "            for num in nums:\n",
    "                dp = ((dp << num) | (dp >> num)) & mask\n",
    "            return dp != 0\n",
    "\n",
    "        left, right = 0, sum(nums)  # 实际的上界为 max(nums)*2\n",
    "        while left <= right:\n",
    "            mid = (left + right) // 2\n",
    "            if check(mid):\n",
    "                right = mid - 1\n",
    "            else:\n",
    "                left = mid + 1\n",
    "        return left"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def unSuitability(self, nums: List[int]) -> int:\n",
    "        def check(mid: int) -> bool:\n",
    "            mask = (1 << (mid + 1)) - 1\n",
    "            dp = mask\n",
    "            for num in nums:\n",
    "                dp = ((dp << num) | (dp >> num)) & mask\n",
    "            return dp != 0\n",
    "\n",
    "        left, right = 0, sum(nums)  \n",
    "        while left <= right:\n",
    "            mid = (left + right) // 2\n",
    "            if check(mid):\n",
    "                right = mid - 1\n",
    "            else:\n",
    "                left = mid + 1\n",
    "        return left\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums):\n",
    "        if len(nums) < 3:\n",
    "            return []\n",
    "\n",
    "        res = []\n",
    "        nums.sort()\n",
    "\n",
    "        if nums[0] == nums[-1] == 0:    # special case, otherwise return [] for [0, 0, 0]\n",
    "            return [[0, 0, 0]]\n",
    "\n",
    "        for i in range(len(nums) - 2):  # iterate for the first number\n",
    "            if nums[i] > 0:             # unnecessary to check if least number sis positive\n",
    "                break\n",
    "            if nums[i] == nums[i-1]:    # avoiding duplication\n",
    "                continue\n",
    "            \n",
    "            l, r = i + 1, len(nums) - 1 # rest 2 numbers start from far edges of afterward\n",
    "\n",
    "            while l < r:\n",
    "                s = nums[i] + nums[l] + nums[r]\n",
    "                if s < 0:               # if neg, increase the smaller one\n",
    "                    l += 1\n",
    "                elif s > 0:             # if pos, decrease the greater one\n",
    "                    r -= 1\n",
    "                if s == 0:              # check, append and reduce duplication\n",
    "                    res.append((nums[i], nums[l], nums[r]))\n",
    "                    while l < r and nums[l] == nums[l + 1]:\n",
    "                        l += 1\n",
    "                    while l < r and nums[r] == nums[r - 1]:\n",
    "                        r -= 1\n",
    "                    l += 1              # see if other pairs check.\n",
    "                    r -= 1\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def fourSumCount(self, nums1: List[int], nums2: List[int], nums3: List[int], nums4: List[int]) -> int:\n",
    "        \n",
    "        # checkup = collections.defaultdict(int)\n",
    "        # n = len(nums1)\n",
    "        # for i in range(n):\n",
    "        #     for j in range(n):\n",
    "        #         if checkup[nums1[i]+nums2[j]] == 0 :\n",
    "        #             checkup[nums1[i]+nums2[j]]=1\n",
    "        #         else:\n",
    "        #             checkup[nums1[i]+nums2[j]]+=1\n",
    "        countAB = collections.Counter(u + v for u in nums1 for v in nums2)\n",
    "        \n",
    "        ans = 0\n",
    "        for u in nums3:\n",
    "            for v in nums4:\n",
    "                if -u -v in countAB:\n",
    "                    ans += countAB[-u-v]\n",
    "        return ans\n",
    "        \n",
    "\n",
    "            \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "\"\"\"\n",
    "# Definition for a Node.\n",
    "class Node:\n",
    "    def __init__(self, val=None, next=None):\n",
    "        self.val = val\n",
    "        self.next = next\n",
    "\"\"\"\n",
    "\n",
    "class Solution:\n",
    "    def insert(self, head: 'Node', insertVal: int) -> 'Node':\n",
    "        if head is None:\n",
    "            head = Node(insertVal,None)\n",
    "            head.next = head\n",
    "            return head\n",
    "        elif head.next == head:\n",
    "            new_node = Node(insertVal, None)\n",
    "            \n",
    "            new_node.next = head\n",
    "            head.next = new_node\n",
    "            return head\n",
    "        \n",
    "        #头部位置 4-> 1 ==> 4->0->1\n",
    "        #中部位置 3-> 7 ==> 3->5->7\n",
    "        #尾部位置 4-> 1 ==> 4->5->1\n",
    "        #特殊情况 全等\n",
    "        pre = head\n",
    "        cur = head.next\n",
    "        while True:\n",
    "            print(f'current check:{pre.val}->{cur.val}') \n",
    "            if pre.val>cur.val:\n",
    "                if pre.val<=insertVal or cur.val>=insertVal:\n",
    "                    pass\n",
    "                    print(pre.val, cur.val)\n",
    "                    new_node = Node(insertVal, None)\n",
    "                    pre.next = new_node\n",
    "                    new_node.next = cur\n",
    "                    # head = new_node\n",
    "                    break\n",
    "            else:\n",
    "                if pre.val<=insertVal and insertVal<=cur.val:\n",
    "                    #插入\n",
    "                    print(pre.val, cur.val)\n",
    "                    new_node = Node(insertVal, None)\n",
    "                    pre.next = new_node\n",
    "                    new_node.next = cur\n",
    "                    # head = new_node\n",
    "                    break\n",
    "            \n",
    "            if cur.next==head.next:\n",
    "                new_node = Node(insertVal, None)\n",
    "                pre.next = new_node\n",
    "                new_node.next = cur\n",
    "                break\n",
    "            \n",
    "            pre = cur\n",
    "            cur = cur.next\n",
    "\n",
    "            \n",
    "            \n",
    "            # if cur==head:\n",
    "            #     break\n",
    "        \n",
    "        return head\n",
    "        \n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def findMinDifference(self, timePoints: List[str]) -> int:\n",
    "        def check(x):\n",
    "            first=i[0:2]\n",
    "            second=i[3:5]\n",
    "            total=int(first)*60+int(second)\n",
    "            return total \n",
    "        list1=[]\n",
    "        for i in timePoints:\n",
    "            list1.append(check(i))\n",
    "        list1.sort()\n",
    "        list1.append(list1[0]+1440)\n",
    "        \n",
    "        list2=[]\n",
    "        for i in range(1,len(list1)):\n",
    "            list2.append(list1[i]-list1[i-1])\n",
    "        \n",
    "        return min(list2)\n",
    "\n",
    "\n",
    "        \n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def findMinDifference(self, timePoints: List[str]) -> int:\n",
    "        def check(tm):\n",
    "            hour,minute = tm.split(':')\n",
    "            return int(hour)*60 + int(minute)\n",
    "        \n",
    "        lst = sorted([check(time) for time in timePoints])\n",
    "        n = len(lst)\n",
    "        ans = lst[0] + 24*60 - lst[-1]\n",
    "        for i in range(n-1):\n",
    "            if lst[i+1] - lst[i] < ans:\n",
    "                ans = lst[i+1] - lst[i]\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def findMinDifference(self, timePoints: List[str]) -> int:\n",
    "        l=[]\n",
    "        for word in timePoints:\n",
    "            l.append(list(map(int,word.split(\":\"))))\n",
    "        l.sort()\n",
    "        ans= (l[0][0]-l[-1][0]+24)*60+(l[0][1]-l[-1][1])\n",
    "        def check(x,y):\n",
    "            return (y[0]-x[0])*60+(y[1]-x[1])\n",
    "        for i in range(1,len(timePoints)):\n",
    "            ans=min(ans,check(l[i-1],l[i]))\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def pathSum(self, root: TreeNode, targetSum: int) -> int:\n",
    "\n",
    "        # top-down or bottom-up should both OK\n",
    "        # prefix sum idea + dfs\n",
    "\n",
    "        # ret = 0\n",
    "        # def dfs(n, d):\n",
    "        #     if not n:\n",
    "        #         return\n",
    "\n",
    "        #     # print({k:v for k, v in d.items() if v != 0})\n",
    "\n",
    "        #     t = targetSum - n.val\n",
    "        #     nonlocal ret\n",
    "        #     # if d[t] != 0:\n",
    "        #     #     print(f'{n.val} {t} {d[t]}')   \n",
    "        #     ret += d[t]\n",
    "\n",
    "        #     # above check is the path start is from root to current parent and end is current\n",
    "        #     # so if t==0 then only current is satisfy the condition\n",
    "        #     # so stand alone check t == 0 make sense\n",
    "        #     if t == 0:\n",
    "        #         ret += 1\n",
    "\n",
    "        #     nd = defaultdict(int)\n",
    "        #     nd[n.val] = 1\n",
    "        #     for k, v in d.items():\n",
    "        #         nd[k+n.val] += v\n",
    "            \n",
    "        #     # for k, v in nd.items():\n",
    "        #     #     d[k] += v\n",
    "\n",
    "        #     dfs(n.left, nd)\n",
    "        #     dfs(n.right, nd)\n",
    "\n",
    "            \n",
    "        #     # for k, v in nd.items():\n",
    "        #     #     d[k] -= v\n",
    "        \n",
    "        # d = defaultdict(int)\n",
    "        # # d[0] = 1\n",
    "        # dfs(root, d)\n",
    "\n",
    "        # return ret\n",
    "\n",
    "        # from ans, above solution doesn't use prefix at all\n",
    "        # d should record the all path sum from root to any ancestor of the cur node (prefix)\n",
    "        # and from root to cur node sum - targetVal if in d, then it means the ancester to cur node equal targetVal\n",
    "        # wholeSum - targetVal = prefixSum\n",
    "        # targetVal = wholeSum - prefixSum\n",
    "        # targetVal = sum(ancester to cur node)\n",
    "\n",
    "        ret = 0\n",
    "        def dfs(n, d, s):\n",
    "            if not n:\n",
    "                return\n",
    "\n",
    "            print({k:v for k, v in d.items() if v != 0})\n",
    "            s += n.val\n",
    "            t = s - targetSum\n",
    "            nonlocal ret\n",
    "            if d[t] != 0:\n",
    "                print(f'{s} {n.val} {t} {d[t]}')   \n",
    "            ret += d[t]\n",
    "\n",
    "            d[s] += 1\n",
    "            \n",
    "            dfs(n.left, d, s)\n",
    "            dfs(n.right, d, s)\n",
    "\n",
    "            d[s] -= 1\n",
    "        \n",
    "        d = defaultdict(int)\n",
    "\n",
    "        # key is put prefix sum(0)\n",
    "        # thus include the situation from root to leaf\n",
    "        # this solution slower than previous unexpected\n",
    "        d[0] = 1\n",
    "        dfs(root, d, 0)\n",
    "\n",
    "        return ret"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def pathSum(self, root: TreeNode, targetSum: int) -> int:\n",
    "\n",
    "        # top-down or bottom-up should both OK\n",
    "        # prefix sum idea + dfs\n",
    "\n",
    "        # ret = 0\n",
    "        # def dfs(n, d):\n",
    "        #     if not n:\n",
    "        #         return\n",
    "\n",
    "        #     # print({k:v for k, v in d.items() if v != 0})\n",
    "\n",
    "        #     t = targetSum - n.val\n",
    "        #     nonlocal ret\n",
    "        #     # if d[t] != 0:\n",
    "        #     #     print(f'{n.val} {t} {d[t]}')   \n",
    "        #     ret += d[t]\n",
    "\n",
    "        #     # above check is the path start is from root to current parent and end is current\n",
    "        #     # so if t==0 then only current is satisfy the condition\n",
    "        #     # so stand alone check t == 0 make sense\n",
    "        #     if t == 0:\n",
    "        #         ret += 1\n",
    "\n",
    "        #     nd = defaultdict(int)\n",
    "        #     nd[n.val] = 1\n",
    "        #     for k, v in d.items():\n",
    "        #         nd[k+n.val] += v\n",
    "            \n",
    "        #     # for k, v in nd.items():\n",
    "        #     #     d[k] += v\n",
    "\n",
    "        #     dfs(n.left, nd)\n",
    "        #     dfs(n.right, nd)\n",
    "\n",
    "            \n",
    "        #     # for k, v in nd.items():\n",
    "        #     #     d[k] -= v\n",
    "        \n",
    "        # d = defaultdict(int)\n",
    "        # # d[0] = 1\n",
    "        # dfs(root, d)\n",
    "\n",
    "        # return ret\n",
    "\n",
    "        # from ans, above solution doesn't use prefix at all\n",
    "        # d should record the all path sum from root to any ancestor of the cur node (prefix)\n",
    "        # and from root to cur node sum - targetVal if in d, then it means the ancester to cur node equal targetVal\n",
    "        # wholeSum - targetVal = prefixSum\n",
    "        # targetVal = wholeSum - prefixSum\n",
    "        # targetVal = sum(ancester to cur node)\n",
    "\n",
    "        ret = 0\n",
    "        def dfs(n, d, s):\n",
    "            if not n:\n",
    "                return\n",
    "\n",
    "            print({k:v for k, v in d.items() if v != 0})\n",
    "            s += n.val\n",
    "            t = s - targetSum\n",
    "            nonlocal ret\n",
    "            if d[t] != 0:\n",
    "                print(f'{s} {n.val} {t} {d[t]}')   \n",
    "            ret += d[t]\n",
    "\n",
    "            d[s] += 1\n",
    "            \n",
    "            dfs(n.left, d, s)\n",
    "            dfs(n.right, d, s)\n",
    "\n",
    "            d[s] -= 1\n",
    "        \n",
    "        d = defaultdict(int)\n",
    "\n",
    "        # key is put prefix sum(0)\n",
    "        # thus include the situation from root to leaf\n",
    "        # this solution slower than previous unexpected\n",
    "        d[0] = 1\n",
    "        dfs(root, d, 0)\n",
    "\n",
    "        return ret"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def findRedundantConnection(self, edges: List[List[int]]) -> List[int]:\n",
    "        n = len(edges)\n",
    "        fa = [i for i in range(n + 1)]\n",
    "        def find(x:int) -> int:\n",
    "            if x == fa[x]: return x\n",
    "            fa[x] = find(fa[x])\n",
    "            return fa[x]\n",
    "        \n",
    "        def merge(x:int, y:int) -> None:\n",
    "            x, y = find(x), find(y)\n",
    "            fa[x] = y\n",
    "\n",
    "        def check(x:int, y:int) -> bool:\n",
    "            return find(x) == find(y)\n",
    "\n",
    "        for edge in edges:\n",
    "            x, y = edge\n",
    "            if check(x, y):\n",
    "                return edge\n",
    "            merge(x, y)\n",
    "        return []"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def findRedundantConnection(self, edges: List[List[int]]) -> List[int]:\n",
    "        n = len(edges)\n",
    "        fa = [i for i in range(n + 1)]\n",
    "        rk = [1 for i in range(n + 1)]\n",
    "\n",
    "        def find(x:int) -> int:\n",
    "            if x == fa[x]: return x\n",
    "            fa[x] = find(fa[x])\n",
    "            return fa[x]\n",
    "        \n",
    "        def merge(x:int, y:int) -> None:\n",
    "            x, y = find(x), find(y)\n",
    "            if rk[x] < rk[y]:\n",
    "                fa[x] = y\n",
    "            else:\n",
    "                if fa[x] == fa[y]:\n",
    "                    rk[y] += 1\n",
    "                fa[y] = x\n",
    "\n",
    "        def check(x:int, y:int) -> bool:\n",
    "            return find(x) == find(y)\n",
    "\n",
    "        for edge in edges:\n",
    "            x, y = edge\n",
    "            if check(x, y):\n",
    "                return edge\n",
    "            merge(x, y)\n",
    "        return []"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Dsu:\n",
    "    def __init__(self, size):\n",
    "        self.pa = [i for i in range(size)]\n",
    "        self.size = [1] * size\n",
    "\n",
    "    def search(self, x):\n",
    "        if self.pa[x] != x:\n",
    "            self.pa[x] = self.search(self.pa[x])\n",
    "        return self.pa[x]\n",
    "\n",
    "    def union(self, x, y):\n",
    "        x, y = self.search(x), self.search(y)\n",
    "        if x == y:\n",
    "            return\n",
    "        if self.size[x] < self.size[y]:\n",
    "            x, y = y, x\n",
    "        self.pa[y] = x\n",
    "        self.size[x] += self.size[y]\n",
    "\n",
    "    def check_connected(self, x, y):\n",
    "        x, y = self.search(x), self.search(y)\n",
    "        return x == y\n",
    "\n",
    "\n",
    "class Solution:\n",
    "    def findRedundantConnection(self, edges: List[List[int]]) -> List[int]:\n",
    "        n = edges.__len__()\n",
    "        dsu = Dsu(n)\n",
    "        for x, y in edges:\n",
    "            if dsu.check_connected(x - 1, y - 1):\n",
    "                return [x, y]\n",
    "            dsu.union(x - 1, y - 1)\n",
    "        return []\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def containsNearbyAlmostDuplicate(self, nums: List[int], k: int, t: int) -> bool:\n",
    "        # n = len(nums)\n",
    "        \n",
    "        def bucket_id(n):\n",
    "            return math.floor(n / ( t + 1))\n",
    "        \n",
    "        bucket =  dict()\n",
    "        def check(i, x):\n",
    "            return i in bucket  and abs(bucket[i] - x) <= t\n",
    "        \n",
    "        for i, v  in enumerate(nums):\n",
    "            bid = bucket_id(v)\n",
    "            if bid in bucket or check(bid + 1, v) or check(bid - 1, v):\n",
    "                return True\n",
    "            bucket[bid] = v\n",
    "            if i > k - 1:\n",
    "                bucket.pop(bucket_id(nums[i - k]))\n",
    "        return False\n",
    "        \n",
    "        \n",
    "        def bucket_id(x: int) -> int:\n",
    "            return math.floor(x / (t + 1))  # 计算桶id\n",
    "\n",
    "        bucket = dict()  # 桶<int,int> id -> 元素\n",
    "\n",
    "        def near(bid, x):\n",
    "            return bid in bucket and abs(bucket[bid] - x) <= t\n",
    "\n",
    "        for i, x in enumerate(nums):\n",
    "            bid = bucket_id(x)\n",
    "            if bid in bucket or near(bid + 1, x) or near(bid - 1, x):\n",
    "                return True\n",
    "            bucket[bid] = x\n",
    "            if i > k - 1:\n",
    "\t             # 将桶的大小控制在 k - 1，以便下一次循环迭代可以再插入一个x\n",
    "                bucket.pop(bucket_id(nums[i - k]))\n",
    "        return False\n",
    "        # pq = []\n",
    "        # kt = [[i for i in range(t+1)] for j in range(k + 1)]\n",
    "        # for i, v in enumerate(nums):\n",
    "        #     heapq.heappush(pq, (v, i))\n",
    "        # for v,index in pq:\n",
    "        #     for i in range(index + 1, n):\n",
    "        #         if abs(pq[i][0] - i) < k and pq[i][1] <= v + t:\n",
    "        #             return True\n",
    "        #         else:\n",
    "        #             break\n",
    "        # return False\n",
    "                \n",
    "                \n",
    "        # for i in range(n):\n",
    "        #     for j in range(n):\n",
    "        #         if i == j or abs(i - j) > k:\n",
    "        #             continue\n",
    "        #         if abs(nums[i] - nums[j]) <=t:\n",
    "        #             return True\n",
    "        # return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def containsNearbyAlmostDuplicate(self, nums: List[int], k: int, t: int) -> bool:\n",
    "        # n = len(nums)\n",
    "        \n",
    "        def bucket_id(n):\n",
    "            return math.floor(n / ( t + 1))\n",
    "        \n",
    "        bucket =  dict()\n",
    "        def check(i, x):\n",
    "            return i in bucket  and abs(bucket[i] - x) <= t\n",
    "        \n",
    "        for i, v  in enumerate(nums):\n",
    "            bid = bucket_id(v)\n",
    "            if bid in bucket or check(bid + 1, v) or check(bid - 1, v):\n",
    "                return True\n",
    "            bucket[bid] = v\n",
    "            if i > k - 1:\n",
    "                bucket.pop(bucket_id(nums[i - k]))\n",
    "        return False\n",
    "        \n",
    "        # pq = []\n",
    "        # kt = [[i for i in range(t+1)] for j in range(k + 1)]\n",
    "        # for i, v in enumerate(nums):\n",
    "        #     heapq.heappush(pq, (v, i))\n",
    "        # for v,index in pq:\n",
    "        #     for i in range(index + 1, n):\n",
    "        #         if abs(pq[i][0] - i) < k and pq[i][1] <= v + t:\n",
    "        #             return True\n",
    "        #         else:\n",
    "        #             break\n",
    "        # return False\n",
    "                \n",
    "                \n",
    "        # for i in range(n):\n",
    "        #     for j in range(n):\n",
    "        #         if i == j or abs(i - j) > k:\n",
    "        #             continue\n",
    "        #         if abs(nums[i] - nums[j]) <=t:\n",
    "        #             return True\n",
    "        # return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def countSubstrings(self, s: str) -> int:\n",
    "        # i~j是否是回文串(d[i][j])\n",
    "        # 1. s[i] == s[j]? \n",
    "        #   1.1 i跟j是否相等; 1.2 s[i]与s[j]是否相等\n",
    "        # 2. d[i+1][j-1]是否是回文串\n",
    "        i = 0\n",
    "        j = len(s)-1\n",
    "        d = [[-1 for i in range(len(s))] for j in range(len(s))]\n",
    "        def check_palindrome(low, high):\n",
    "            if low == high or (high == low+1 and s[high] == s[low]):\n",
    "                return 1\n",
    "            if s[low] == s[high]:\n",
    "                if d[low+1][high-1] == -1:\n",
    "                    d[low+1][high-1] = check_palindrome(low+1, high-1)\n",
    "                return d[low+1][high-1]\n",
    "            return 0\n",
    "        # print(d)\n",
    "        res = 0\n",
    "        for i in range(len(s)):\n",
    "            for j in range(i,len(s)):\n",
    "                if d[i][j] == -1:\n",
    "                    d[i][j] = check_palindrome(i, j)\n",
    "                res += d[i][j]\n",
    "        # print(d)\n",
    "        # res = sum(sum(i) for i in d)\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def countSubstrings(self, s: str) -> int:\n",
    "        \n",
    "        @cache\n",
    "        def check(i,j):\n",
    "            while i<j:\n",
    "                if s[i]!=s[j]:\n",
    "                    return False\n",
    "                i+=1\n",
    "                j-=1\n",
    "            return True\n",
    "        \n",
    "\n",
    "        res=0\n",
    "        for i in range(len(s)):\n",
    "            for j in range(i,len(s)):\n",
    "                if check(i,j):\n",
    "                    res+=1\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addBoldTag(self, s: str, words: List[str]) -> str:\n",
    "        n = len(s)\n",
    "        bold = [False] * n\n",
    "        # iterate through every index position of string\n",
    "        # for every index position, iterate through every word to check if it is a prefix of current substring, if so, mark is as bolded\n",
    "        for i in range(n):\n",
    "            for w in words:\n",
    "                if s[i:].startswith(w):\n",
    "                    bold[i:i+len(w)] = [True] * len(w)\n",
    "        # combine all the bolded booleans into bold tags\n",
    "        res = \"\"\n",
    "        for i in range(n):\n",
    "            # current position is the start of bold\n",
    "            if bold[i] and (i == 0 or not bold[i-1]):\n",
    "                res += \"<b>\"\n",
    "            res += s[i]\n",
    "            # current position is the end of bold\n",
    "            if bold[i] and (i == n-1 or not bold[i+1]):\n",
    "                res += \"</b>\"\n",
    "        return res\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isAdditiveNumber(self, num: str) -> bool:\n",
    "        n = len(num)\n",
    "        if n < 3: return False\n",
    "        def check(p1, p2, j):\n",
    "            while j < n:\n",
    "                p = str(int(p1) + int(p2))\n",
    "                if num[j: j+len(p)] != p:\n",
    "                    return False\n",
    "                j += len(p)\n",
    "                p1, p2 = p2, p\n",
    "            return True\n",
    "        for i in range(1, n//2+1) if num[0] != \"0\" else [1]:\n",
    "            for j in range(i+1, n) if num[i] != \"0\" else [i+1]:\n",
    "                p1 = num[:i]\n",
    "                p2 = num[i:j]\n",
    "                if check(p1, p2, j):\n",
    "                    return True\n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isAdditiveNumber(self, num: str) -> bool:\n",
    "        def check(a,b):\n",
    "            if a.startswith('0') and a!='0' or b.startswith('0') and b!='0' :\n",
    "                return False\n",
    "            temp = a + b\n",
    "            while len(temp)<len(num):\n",
    "                a,b = b,str(int(a)+int(b))\n",
    "                temp += b\n",
    "            return temp == num\n",
    "        for i in range(1,len(num)-1):\n",
    "            for j in range(i):\n",
    "                if  check(num[:j+1],num[j+1:i+1]):\n",
    "                    return True\n",
    "        return False\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isAdditiveNumber(self, num: str) -> bool:\n",
    "        def check(i, j, k):\n",
    "            if j-i > 1 and num[i] == '0' or k-j > 1 and num[j] == '0':\n",
    "                return False\n",
    "            nxt = str(int(num[i:j]) + int(num[j:k]))\n",
    "            if not num[k:].startswith(nxt):\n",
    "                return k==n\n",
    "            return check(j, k, k+len(nxt))\n",
    "\n",
    "        n = len(num)\n",
    "        return any(check(0, i, j) for i in range(1, n-1) for j in range(i+1, n) )\n",
    "        # for i in range(1, n-1):\n",
    "        #     for j in range(i+1, n):\n",
    "        #         if check(0, i, j):\n",
    "        #             return True\n",
    "        # return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isAdditiveNumber(self, num: str) -> bool:\n",
    "        def check(i, j, k):\n",
    "            if j-i > 1 and num[i] == '0' or k-j > 1 and num[j] == '0':\n",
    "                return False\n",
    "            nxt = str(int(num[i:j]) + int(num[j:k]))\n",
    "            if not num[k:].startswith(nxt):\n",
    "                return k==n\n",
    "            return check(j, k, k+len(nxt))\n",
    "\n",
    "        n = len(num)\n",
    "        for i in range(1, n-1):\n",
    "            for j in range(i+1, n):\n",
    "                if check(0, i, j):\n",
    "                    return True\n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isAdditiveNumber(self, num: str) -> bool:\n",
    "        n = len(num)\n",
    "        if n < 3: return False\n",
    "        def check(p1, p2, j):\n",
    "            while j < n:\n",
    "                p = str(int(p1) + int(p2))\n",
    "                if num[j: j+len(p)] != p:\n",
    "                    return False\n",
    "                j += len(p)\n",
    "                p1, p2 = p2, p\n",
    "            return True\n",
    "        for i in range(1, n//2+1) if num[0] != \"0\" else [1]:\n",
    "            for j in range(i+1, n) if num[i] != \"0\" else [i+1]:\n",
    "                p1 = num[:i]\n",
    "                p2 = num[i:j]\n",
    "                if check(p1, p2, j):\n",
    "                    return True\n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    \n",
    "    def __init__(self):\n",
    "        self.nums = []\n",
    "    def checkNum(self, num):\n",
    "        if num[0]=='0' and len(num) > 1:\n",
    "            return False\n",
    "        return True\n",
    "    def dfs(self,num,start):\n",
    "        if len(self.nums) >= 3:\n",
    "            if self.nums[-1] != self.nums[-2] + self.nums[-3]:\n",
    "                return False\n",
    "            if start == len(num):\n",
    "                return True\n",
    "        for end in range(start,len(num)):\n",
    "            curStr = num[start:end+1]\n",
    "            if not self.checkNum(curStr):\n",
    "                continue\n",
    "            self.nums.append(int(curStr))\n",
    "            if self.dfs(num, end + 1):\n",
    "                return True\n",
    "            self.nums.pop()\n",
    "        return False\n",
    "    def isAdditiveNumber(self, num: str) -> bool:\n",
    "        return self.dfs(num, 0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isAdditiveNumber(self, num: str) -> bool:\n",
    "        def check(a, b):\n",
    "            if (a.startswith(\"0\") and a != \"0\") or (b.startswith(\"0\") and b != \"0\"):\n",
    "                return False\n",
    "            temp = a + b\n",
    "            a, b = b, str(int(b) + int(a))\n",
    "            temp += b\n",
    "            while len(temp) < len(num):\n",
    "                a, b = b, str(int(b) + int(a))\n",
    "                temp += b\n",
    "            return num == temp\n",
    "\n",
    "        for j in range(1, len(num) - 1):\n",
    "            for i in range(j):\n",
    "                if check(num[: i + 1], num[i + 1 : j + 1]):\n",
    "                    return True\n",
    "        return False\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isAdditiveNumber(self, num: str) -> bool:\n",
    "        total_len = len(num)\n",
    "\n",
    "        def check_valid(v1, v2, idx):\n",
    "            su = v1 + v2\n",
    "            ssu = str(su)\n",
    "            end = idx + len(ssu)\n",
    "            if end > total_len:\n",
    "                return False\n",
    "            p3 = num[idx: end]\n",
    "            if p3 == ssu:\n",
    "                if total_len == end:\n",
    "                    return True\n",
    "                return check_valid(v2, su, end)\n",
    "            return False\n",
    "        mem = {}\n",
    "\n",
    "        def get_num(a, b):\n",
    "            if mem.get((a,b)):\n",
    "                return False\n",
    "            mem[(a,b)] = True\n",
    "\n",
    "            rest_len = total_len - a - b\n",
    "            if rest_len < a or rest_len < b:\n",
    "                return False\n",
    "                \n",
    "            v1 = num[:a]\n",
    "            v2 = num[a:a + b]\n",
    "\n",
    "            if v1 != \"0\" and v1.startswith(\"0\"):\n",
    "                return False\n",
    "            if v2 != \"0\" and v2.startswith(\"0\"):\n",
    "                return False\n",
    "\n",
    "            iv1 = int(v1)\n",
    "            iv2 = int(v2)\n",
    "\n",
    "            if check_valid(iv1, iv2, a + b):\n",
    "                return True\n",
    "\n",
    "            if get_num(a + 1, b):\n",
    "                return True\n",
    "\n",
    "            if get_num(a, b + 1):\n",
    "                return True\n",
    "\n",
    "            return False\n",
    "\n",
    "        return get_num(1, 1)\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\r\n",
    "    def isAdditiveNumber(self, num: str) -> bool:\r\n",
    "        n = len(num)\r\n",
    "\r\n",
    "        def check(pre_0, pre_1, s):\r\n",
    "            # print(pre_0, pre_1, s)\r\n",
    "            if not s:\r\n",
    "                return True\r\n",
    "            prefix = str(int(pre_0) + int(pre_1))\r\n",
    "            if not s.startswith(prefix):\r\n",
    "                return False\r\n",
    "            else:\r\n",
    "                return check(pre_1, prefix, s[len(prefix):])\r\n",
    "        \r\n",
    "        for i in range(1, n):\r\n",
    "            pre_0 = num[:i]\r\n",
    "            if i > 1 and num[0] == '0':\r\n",
    "                break\r\n",
    "            for j in range(i + 1, n):\r\n",
    "                if n - j < i or n - j < j - i:\r\n",
    "                    break\r\n",
    "                if j - i > 1 and num[i] == '0':\r\n",
    "                    break\r\n",
    "                pre_1 = num[i: j]\r\n",
    "                if check(pre_0, pre_1, num[j:]):\r\n",
    "                    return True\r\n",
    "        return False\r\n",
    "\r\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isAdditiveNumber(self, num: str) -> bool:\n",
    "        total_len = len(num)\n",
    "\n",
    "        def check_valid(v1, v2, idx):\n",
    "            su = v1 + v2\n",
    "            ssu = str(su)\n",
    "            if idx + len(ssu) > total_len:\n",
    "                return False\n",
    "            p3 = num[idx: idx + len(ssu)]\n",
    "            if p3 == ssu:\n",
    "                if total_len == idx + len(ssu):\n",
    "                    return True\n",
    "                return check_valid(v2, su, idx + len(ssu))\n",
    "            return False\n",
    "\n",
    "        def get_num(a, b):\n",
    "            if a + b > (total_len // 3 * 2 + (total_len % 3 and 1)):\n",
    "                return False\n",
    "            v1 = num[:a]\n",
    "            v2 = num[a:a + b]\n",
    "\n",
    "            if v1 != \"0\" and v1.startswith(\"0\"):\n",
    "                return False\n",
    "            if v2 != \"0\" and v2.startswith(\"0\"):\n",
    "                return False\n",
    "\n",
    "            iv1 = int(v1)\n",
    "            iv2 = int(v2)\n",
    "\n",
    "            if check_valid(iv1, iv2, a + b):\n",
    "                return True\n",
    "\n",
    "            if get_num(a + 1, b):\n",
    "                return True\n",
    "\n",
    "            if get_num(a, b + 1):\n",
    "                return True\n",
    "\n",
    "            return False\n",
    "\n",
    "        return get_num(1, 1)\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isAdditiveNumber(self, num: str) -> bool:\n",
    "        def check(i, j, k):\n",
    "            if j-i > 1 and num[i] == '0' or k-j > 1 and num[j] == '0':\n",
    "                return False\n",
    "            nxt = str(int(num[i:j]) + int(num[j:k]))\n",
    "            print(i, j, k, nxt)\n",
    "            if not num[k:].startswith(nxt):\n",
    "                return k==n\n",
    "            return check(j, k, k+len(nxt))\n",
    "\n",
    "        n = len(num)\n",
    "        for i in range(1, n-1):\n",
    "            for j in range(i+1, n):\n",
    "                print(i,j)\n",
    "                if check(0, i, j):\n",
    "                    return True\n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "import random\r\n",
    "class Solution:\r\n",
    "    def rearrangeArray(self, nums: List[int]) -> List[int]:\r\n",
    "        def check(nums: List[int]):\r\n",
    "            for i in range(1, len(nums) - 1):\r\n",
    "                if nums[i] == (nums[i - 1] + nums[i + 1]) / 2:\r\n",
    "                    return False\r\n",
    "\r\n",
    "            return True\r\n",
    "\r\n",
    "        while not check(nums):\r\n",
    "            random.shuffle(nums)\r\n",
    "\r\n",
    "        return nums\r\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def trulyMostPopular(self, names: List[str], synonyms: List[str]) -> List[str]:\n",
    "        namelist = {} #名字列表 名字:[idx,次数]\n",
    "        idx = 0\n",
    "        def check(x,nn):\n",
    "            nonlocal idx\n",
    "            if x not in namelist:\n",
    "                namelist[x]=[idx,nn]\n",
    "                idx+=1\n",
    "        \n",
    "        for s in names:\n",
    "            na,time = s[:-1].split(\"(\")\n",
    "            check(na,int(time))\n",
    "        for s in synonyms:\n",
    "            x,y = s[1:-1].split(\",\")\n",
    "            check(x,0)\n",
    "            check(y,0)\n",
    "        print(namelist)\n",
    "\n",
    "        N = len(namelist)\n",
    "        father = list(range(N))\n",
    "        def find(x):\n",
    "            if x!=father[x]:\n",
    "                father[x]=find(father[x])\n",
    "            return father[x]\n",
    "        def unit(x,y):\n",
    "            fx,fy = find(x),find(y)\n",
    "            if fx<fy:father[fy]=fx\n",
    "            else:father[fx]=fy\n",
    "        for s in synonyms:\n",
    "            x,y = s[1:-1].split(\",\")\n",
    "            unit(namelist[x][0],namelist[y][0])\n",
    "        temp = defaultdict(list)\n",
    "        for k,v in namelist.items():\n",
    "            f = find(v[0])\n",
    "            if not temp[f]:\n",
    "                temp[f].append(v[1])\n",
    "            else:\n",
    "                temp[f][0]+=v[1]\n",
    "            temp[f].append(k)\n",
    "        print(temp)\n",
    "        return [sorted(arr[1:])[0]+\"(\"+str(arr[0])+\")\" for arr in temp.values()]\n",
    "\n",
    "\n",
    "        \n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def countArrangement(self, n: int) -> int:\n",
    "        \"\"\"DP\"\"\"\n",
    "        # state's i-th bit show if a value(i) is used\n",
    "        states = 1 << n\n",
    "        # [0 for _ in range(states)] show all states from 0 to 0...111\n",
    "        dp = [[0 for _ in range(states)] for _ in range(n+1)]\n",
    "        dp[0][0] = 1\n",
    "\n",
    "        for idx in range(1, n+1):\n",
    "        # go through all idx from 1 to n\n",
    "            for msk in range(states):\n",
    "            # go through all state from 0 to 0...111\n",
    "                if bin(msk).count('1') != idx:\n",
    "                # check if the msk match idx first\n",
    "                    continue\n",
    "                for k in range(1, n+1):\n",
    "                # find k that satisfy 2 conditions\n",
    "                    if msk >> (k-1) & 1 == 0:\n",
    "                    # 1st: k should be exist and corresponding msk is valid\n",
    "                        continue\n",
    "                    \n",
    "                    if k % idx == 0 or idx % k == 0:\n",
    "                    # 2nd reason to check if it's valid\n",
    "                        # add up all possible pre-state that satisfy current state(msk)\n",
    "                        dp[idx][msk] += dp[idx - 1][msk ^ (1 << (k-1))]\n",
    "        # aka retuen dp[n][state - 1]\n",
    "        return dp[-1][-1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def findCircleNum(self, isConnected: List[List[int]]) -> int:\n",
    "        n = len(isConnected)\n",
    "        cities = {i: None for i in range(n)}\n",
    "        checked_bag = {(i, j): None for i in range(n) for j in range(n)}\n",
    "\n",
    "        if n == 1:\n",
    "            return 1\n",
    "\n",
    "        def method(frontier, group):\n",
    "            while frontier:\n",
    "                i = frontier.pop()\n",
    "                for j in range(n):\n",
    "                    checked_bag[(i, j)] = True\n",
    "                    if isConnected[i][j] is 1:\n",
    "                        if j not in frontier and cities[j] is None:\n",
    "                            frontier = [j] + frontier\n",
    "                        cities[i] = group\n",
    "                        cities[j] = group\n",
    "        group = 0\n",
    "        for i in range(n):\n",
    "            if cities[i] is None:\n",
    "                group += 1\n",
    "                method([i], group)\n",
    "        return group\n",
    "    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def findCircleNum(self, isConnected: List[List[int]]) -> int:\n",
    "        n = len(isConnected)\n",
    "        cnt = 0\n",
    "        checked = [False] * n\n",
    "\n",
    "        def dfs(i):\n",
    "            checked[i] = True\n",
    "            for j in range(n):\n",
    "                if isConnected[i][j] and not checked[j]:\n",
    "                    checked[j] = True\n",
    "                    dfs(j)\n",
    "\n",
    "        for i in range(n):\n",
    "            if not checked[i]:\n",
    "                cnt += 1\n",
    "                dfs(i)\n",
    "\n",
    "        return cnt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def domino(self, n: int, m: int, broken: List[List[int]]) -> int:\n",
    "        x =[]\n",
    "        y = []\n",
    "        for i in range(n):\n",
    "            for j in range(m):\n",
    "                if (i+j)%2 == 0 and [i,j] not in broken:\n",
    "                    x.append([i,j])\n",
    "                elif (i+j)%2 == 1 and [i,j] not in broken:\n",
    "                    y.append([i,j])\n",
    "        def check(x,y):\n",
    "            if abs(x[0]-y[0])+abs(x[1]-y[1]) == 1:\n",
    "                return True \n",
    "            else:\n",
    "                return False\n",
    "        def find(y,visited,choose,xs):\n",
    "            for j,x in enumerate(xs):\n",
    "                if check(x,y) and not visited[j]:\n",
    "                    visited[j] = True\n",
    "                    if choose[j] == -1 or find(choose[j],visited,choose,xs):\n",
    "                        choose[j] = y\n",
    "                        return True \n",
    "            return False\n",
    "        choose = [-1] * len(x)\n",
    "        ans = 0\n",
    "        for i in y:\n",
    "            visited = [False] * len(x)\n",
    "            if find(i,visited,choose,x): \n",
    "                ans += 1\n",
    "        return ans\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    @staticmethod\n",
    "    def check_symbol(s):\n",
    "        if '*' in s:\n",
    "            return True\n",
    "        elif '/' in s:\n",
    "            return True\n",
    "        else:\n",
    "            return False\n",
    "\n",
    "    def calculate(self, s: str) -> int:\n",
    "        # 去空格，并获取\n",
    "        _s_lst = s.replace(' ', '').replace('+', ' + ').replace('-', ' + -').replace('*', ' * ').replace('/', ' / ').split()\n",
    "        _int_lst = [int(n) if n not in ['+', '-', '*', '/'] else n for n in _s_lst]\n",
    "\n",
    "        while self.check_symbol(_int_lst):\n",
    "            for index, value in enumerate(_int_lst):\n",
    "                if value in ['*', '/']:\n",
    "                    if value == '/':\n",
    "                        symbol_flag = -1 if _int_lst[index - 1] < 0 else 1\n",
    "                    else:\n",
    "                        symbol_flag = 1\n",
    "\n",
    "                    _temp = _int_lst[index - 1] * _int_lst[index + 1] if value == '*' else abs(_int_lst[index - 1]) // _int_lst[index + 1]\n",
    "                    del _int_lst[index - 1]\n",
    "                    del _int_lst[index - 1]\n",
    "                    _int_lst[index - 1] = _temp * symbol_flag\n",
    "                    break\n",
    "\n",
    "        result_lst = [n for n in _int_lst if n not in ['-', '+']]\n",
    "        return sum(result_lst)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def camelMatch(self, queries: List[str], pattern: str) -> List[bool]:\n",
    "        self.k=len(pattern)\n",
    "        self.s ={'G', 'X', 'B', 'Q', 'I', 'D', 'T', 'U', 'C', 'A', 'M', 'F', 'N', 'W', 'Y', 'Z', 'E', 'S', 'R', 'K', 'V', 'H', 'O', 'P', 'J', 'L'}\n",
    "\n",
    "\n",
    "        def check(a):\n",
    "            i=j=0\n",
    "            n=len(a)\n",
    "            while i<n:\n",
    "                if a[i]==pattern[j]:\n",
    "                    i+=1 \n",
    "                    j+=1\n",
    "                else:\n",
    "                    if a[i] in self.s:\n",
    "                        return False\n",
    "                    i+=1\n",
    "\n",
    "                if j==self.k:\n",
    "                    break\n",
    "            for w in range(i,n):\n",
    "                if a[w] in self.s:\n",
    "                    return False \n",
    "            return j==self.k\n",
    "                \n",
    "\n",
    "        return [check(v) for v in queries]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Trie:\n",
    "    def __init__(self,):\n",
    "        self.children = dict()\n",
    "        self.isEnd = False\n",
    "    \n",
    "    def insert(self, word: str) -> None:\n",
    "        cur = self\n",
    "        for ch in word:\n",
    "            if ch not in cur.children:\n",
    "                cur.children[ch] = Trie()\n",
    "            cur = cur.children[ch]\n",
    "        cur.isEnd = True\n",
    "\n",
    "    def search(self, word: str) -> bool:\n",
    "        cur = self\n",
    "        for ch in word:\n",
    "            if not ch.isupper():\n",
    "                if ch not in cur.children:\n",
    "                    continue\n",
    "            else:\n",
    "                if ch not in cur.children:\n",
    "                    return False\n",
    "            cur = cur.children[ch]\n",
    "        return cur.isEnd\n",
    "\n",
    "class Solution:\n",
    "    def camelMatch(self, queries: List[str], pattern: str) -> List[bool]:\n",
    "        # lenp = len(pattern)\n",
    "        # def check(s):\n",
    "        #     ls, lp, lens = 0, 0, len(s)\n",
    "        #     while ls < lens and lp < lenp:\n",
    "        #         if s[ls] == pattern[lp]: lp += 1\n",
    "        #         elif s[ls].isupper(): return False\n",
    "        #         ls += 1\n",
    "        #     return lp == lenp and len(list(filter(lambda x: x.isupper(), s[ls:]))) == 0\n",
    "        # return [check(s) for s in queries]\n",
    "        dict_tree = Trie()\n",
    "        dict_tree.insert(pattern)\n",
    "        return [dict_tree.search(query) for query in queries]\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Trie:\n",
    "    def __init__(self,):\n",
    "        self.children = dict()\n",
    "        self.isEnd = False\n",
    "    \n",
    "    def insert(self, word: str) -> None:\n",
    "        cur = self\n",
    "        for ch in word:\n",
    "            if ch not in cur.children:\n",
    "                cur.children[ch] = Trie()\n",
    "            cur = cur.children[ch]\n",
    "        cur.isEnd = True\n",
    "\n",
    "    def search(self, word: str) -> bool:\n",
    "        cur = self\n",
    "        for ch in word:\n",
    "            if not ch.isupper():\n",
    "                # 不匹配的小写字母跳过，这个操作很巧妙，不会移动cur\n",
    "                if ch not in cur.children:\n",
    "                    continue\n",
    "            else:\n",
    "                if ch not in cur.children:\n",
    "                    return False\n",
    "            cur = cur.children[ch]\n",
    "        return cur.isEnd\n",
    "\n",
    "class Solution:\n",
    "    def camelMatch(self, queries: List[str], pattern: str) -> List[bool]:\n",
    "        # lenp = len(pattern)\n",
    "        # def check(s):\n",
    "        #     ls, lp, lens = 0, 0, len(s)\n",
    "        #     while ls < lens and lp < lenp:\n",
    "        #         if s[ls] == pattern[lp]: lp += 1\n",
    "        #         elif s[ls].isupper(): return False\n",
    "        #         ls += 1\n",
    "        #     return lp == lenp and len(list(filter(lambda x: x.isupper(), s[ls:]))) == 0\n",
    "        # return [check(s) for s in queries]\n",
    "        dict_tree = Trie()\n",
    "        dict_tree.insert(pattern)\n",
    "        return [dict_tree.search(query) for query in queries]\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Trie:\n",
    "    def __init__(self,):\n",
    "        self.children = dict()\n",
    "        self.isEnd = False\n",
    "    \n",
    "    def insert(self, word: str) -> None:\n",
    "        cur = self\n",
    "        for ch in word:\n",
    "            if ch not in cur.children:\n",
    "                cur.children[ch] = Trie()\n",
    "            cur = cur.children[ch]\n",
    "        cur.isEnd = True\n",
    "\n",
    "    def search(self, word: str) -> bool:\n",
    "        cur = self\n",
    "        for ch in word:\n",
    "            if not ch.isupper():\n",
    "                # 不匹配的小写字母跳过，这个操作很巧妙，不会移动cur\n",
    "                if ch not in cur.children:\n",
    "                    continue\n",
    "            else:\n",
    "                if ch not in cur.children:\n",
    "                    return False\n",
    "            cur = cur.children[ch]\n",
    "        return cur.isEnd\n",
    "\n",
    "class Solution:\n",
    "    def camelMatch(self, queries: List[str], pattern: str) -> List[bool]:\n",
    "        # lenp = len(pattern)\n",
    "        # def check(s):\n",
    "        #     ls, lp, lens = 0, 0, len(s)\n",
    "        #     while ls < lens and lp < lenp:\n",
    "        #         if s[ls] == pattern[lp]: lp += 1\n",
    "        #         elif s[ls].isupper(): return False\n",
    "        #         ls += 1\n",
    "        #     return lp == lenp and len(list(filter(lambda x: x.isupper(), s[ls:]))) == 0\n",
    "        # return [check(s) for s in queries]\n",
    "        dict_tree = Trie()\n",
    "        dict_tree.insert(pattern)\n",
    "        return [dict_tree.search(query) for query in queries]\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def camelMatch(self, queries: List[str], pattern: str) -> List[bool]:\n",
    "        self.k=len(pattern)\n",
    "        self.s ={'G', 'X', 'B', 'Q', 'I', 'D', 'T', 'U', 'C', 'A', 'M', 'F', 'N', 'W', 'Y', 'Z', 'E', 'S', 'R', 'K', 'V', 'H', 'O', 'P', 'J', 'L'}\n",
    "        def check(a):\n",
    "            x=1\n",
    "            i=j=0\n",
    "            n=len(a)\n",
    "            while i<n:\n",
    "                if a[i]==pattern[j]:\n",
    "                    j+=1\n",
    "                else:\n",
    "                    if a[i] in self.s:\n",
    "                        return False\n",
    "                i+=1\n",
    "                if j==self.k:\n",
    "                    x=0\n",
    "                    break\n",
    "            if x:return False\n",
    "            for w in range(i,n):\n",
    "                if a[w] in self.s:\n",
    "                    return False \n",
    "            return True\n",
    "\n",
    "        return [check(v) for v in queries]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def camelMatch(self, queries: List[str], pattern: str) -> List[bool]:\n",
    "        def check(s, t):\n",
    "            m, n = len(s), len(t)\n",
    "            i = j = 0\n",
    "            while j < n:\n",
    "                while i < m and s[i] != t[j] and s[i].islower():\n",
    "                    i += 1\n",
    "                if i == m or s[i] != t[j]:\n",
    "                    return False\n",
    "                i, j = i + 1, j + 1\n",
    "            while i < m and s[i].islower():\n",
    "                i += 1\n",
    "            return i == m\n",
    "\n",
    "        return [check(q, pattern) for q in queries]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def camelMatch(self, queries: List[str], pattern: str) -> List[bool]:\n",
    "        def check(s, t):\n",
    "            m, n = len(s), len(t)\n",
    "            i = j = 0\n",
    "            while j < n:\n",
    "                while i < m and s[i] != t[j] and s[i].islower():\n",
    "                    i += 1\n",
    "                if i == m or s[i] != t[j]:\n",
    "                    return False\n",
    "                i, j = i + 1, j + 1\n",
    "            while i < m and s[i].islower():\n",
    "                i += 1\n",
    "            return i == m\n",
    "\n",
    "        return [check(q, pattern) for q in queries]\n",
    "\n",
    "# 作者：ylb\n",
    "# 链接：https://leetcode.cn/problems/camelcase-matching/solutions/2225856/python3javacgotypescript-yi-ti-yi-jie-sh-vr5x/\n",
    "# 来源：力扣（LeetCode）\n",
    "# 著作权归作者所有。商业转载请联系作者获得授权，非商业转载请注明出处。\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def camelMatch(self, queries: List[str], pattern: str) -> List[bool]:\n",
    "        self.k=len(pattern)\n",
    "        self.s ={'G', 'X', 'B', 'Q', 'I', 'D', 'T', 'U', 'C', 'A', 'M', 'F', 'N', 'W', 'Y', 'Z', 'E', 'S', 'R', 'K', 'V', 'H', 'O', 'P', 'J', 'L'}\n",
    "        def check(a):\n",
    "            x=1\n",
    "            i=j=0\n",
    "            n=len(a)\n",
    "            while i<n:\n",
    "                if a[i]==pattern[j]:\n",
    "                    j+=1\n",
    "                else:\n",
    "                    if a[i] in self.s:return False\n",
    "                i+=1\n",
    "                if j==self.k:\n",
    "                    x=0\n",
    "                    break\n",
    "            if x:return False\n",
    "            for w in range(i,n):\n",
    "                if a[w] in self.s:\n",
    "                    return False \n",
    "            return True\n",
    "\n",
    "        return [check(v) for v in queries]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def camelMatch(self, queries: List[str], pattern: str) -> List[bool]:\n",
    "        \n",
    "        def check(a,b):\n",
    "            na=len(a)\n",
    "            nb=len(b)\n",
    "            i=0\n",
    "            j=0\n",
    "            while i<na:\n",
    "                if j<nb:\n",
    "                    if a[i]==b[j]:\n",
    "                        j=j+1\n",
    "                    elif a[i].isupper():\n",
    "                        return False\n",
    "                else:\n",
    "                    if a[i].isupper():\n",
    "                        return False\n",
    "                i=i+1\n",
    "            if j==nb:\n",
    "                return True\n",
    "            return False\n",
    "        ans=[0]*len(queries)\n",
    "\n",
    "        for i,v in enumerate(queries):\n",
    "            ans[i]=check(v,pattern)\n",
    "        return ans\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def camelMatch(self, queries: List[str], pattern: str) -> List[bool]:\n",
    "        self.k=len(pattern)\n",
    "        self.s ={'G', 'X', 'B', 'Q', 'I', 'D', 'T', 'U', 'C', 'A', 'M', 'F', 'N', 'W', 'Y', 'Z', 'E', 'S', 'R', 'K', 'V', 'H', 'O', 'P', 'J', 'L'}\n",
    "        def check(a):\n",
    "            x=1\n",
    "            i=j=0\n",
    "            n=len(a)\n",
    "            while i<n:\n",
    "                if a[i]==pattern[j]:\n",
    "                    j+=1\n",
    "                else:\n",
    "                    if a[i] in self.s:return False\n",
    "                i+=1\n",
    "                if j==self.k:\n",
    "                    x=0\n",
    "                    break\n",
    "            if x:return False\n",
    "            for w in range(i,n):\n",
    "                if a[w] in self.s:\n",
    "                    return False \n",
    "            return True\n",
    "\n",
    "        return [check(v) for v in queries]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def camelMatch(self, queries: List[str], pattern: str) -> List[bool]:\n",
    "        lenp = len(pattern)\n",
    "        def check(s):\n",
    "            ls, lp, lens = 0, 0, len(s)\n",
    "            while ls < lens and lp < lenp:\n",
    "                if s[ls] == pattern[lp]: lp += 1\n",
    "                elif s[ls].isupper(): return False\n",
    "                ls += 1\n",
    "            return lp == lenp and len(list(filter(lambda x: x.isupper(), s[ls:]))) == 0\n",
    "\n",
    "        return [check(s) for s in queries]\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def camelMatch(self, queries: List[str], pattern: str) -> List[bool]:\n",
    "        def check(word,pattern):\n",
    "            l=0\n",
    "            n=len(pattern)\n",
    "            for i in range(len(word)):\n",
    "                if word[i].isupper() and (l>=n or (l<=n-1 and word[i]!=pattern[l])):\n",
    "                    return False\n",
    "                if l<=n-1 and word[i]==pattern[l]:\n",
    "                    l+=1\n",
    "            return l==n\n",
    "        res=[]\n",
    "        for each in queries:\n",
    "            res.append(check(each,pattern))\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def camelMatch(self, queries: List[str], pattern: str) -> List[bool]:\n",
    "        \n",
    "        def check():\n",
    "            i = 0\n",
    "            for w in word:\n",
    "                if i < n and w == pattern[i]:\n",
    "                    i += 1\n",
    "                else:\n",
    "                    if w.isupper():\n",
    "                        return False\n",
    "            return i == n\n",
    "        \n",
    "        n = len(pattern)\n",
    "        ans = []\n",
    "        for word in queries:\n",
    "            ans.append(check())\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def camelMatch(self, queries: List[str], pattern: str) -> List[bool]:\n",
    "        # Q = []\n",
    "        # for query in queries:\n",
    "        #     res = \"\"\n",
    "        #     for ch in query:\n",
    "        #         if 65 <= ord(ch) <= 90:\n",
    "        #             res += ch\n",
    "        #     Q.append(res)\n",
    "        # res = []\n",
    "        # for q in Q:\n",
    "        #     if q == pattern:\n",
    "        #         res.append(True)\n",
    "        #     else:\n",
    "        #         res.append(False)\n",
    "        # return res\n",
    "        def check(s, t):\n",
    "            m = len(s)\n",
    "            n = len(t)\n",
    "            i = j = 0\n",
    "            while j < n:\n",
    "                while i < m and s[i] != t[j] and s[i].islower():\n",
    "                    i += 1\n",
    "                if i == m or s[i] != t[j]:\n",
    "                    return False\n",
    "                i, j = i + 1, j + 1\n",
    "            while i < m and s[i].islower():\n",
    "                i += 1\n",
    "            return i == m\n",
    "        return [check(q, pattern) for q in queries]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def camelMatch(self, queries: List[str], pattern: str) -> List[bool]:\n",
    "        def check(s, pattern):\n",
    "            m, n = len(s), len(pattern)\n",
    "            i, j = 0, 0\n",
    "            while i < m and j < n:\n",
    "                if s[i] == pattern[j]:\n",
    "                    j += 1\n",
    "                    i += 1\n",
    "                elif i < m:\n",
    "                    if not s[i].islower():\n",
    "                        break\n",
    "                    else:\n",
    "                        i += 1\n",
    "            if j < n:\n",
    "                return False\n",
    "            while i < m:\n",
    "                if not s[i].islower():\n",
    "                    return False\n",
    "                i += 1\n",
    "            return True\n",
    "        \n",
    "        ans = [check(s, pattern) for s in queries]\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def camelMatch(self, queries: List[str], pattern: str) -> List[bool]:\n",
    "        def check(item, pattern):\n",
    "            i , j = 0 , 0\n",
    "            while j < len(pattern):\n",
    "                while i < len(item) and item[i] != pattern[j] and item[i].islower():\n",
    "                    #跳过不相同的item小写部分\n",
    "                    i += 1\n",
    "                if i == len(item) or item[i] != pattern[j]:\n",
    "                  #如果到字符串末尾,或大写字母不匹配\n",
    "                    return False\n",
    "                i += 1\n",
    "                j += 1\n",
    "\n",
    "            while i < len(item) and item[i].islower():\n",
    "                #跳过末尾的item小写部分\n",
    "                i += 1\n",
    "            return i == len(item)#如果在跳过末尾小写部分时遇到大写,则i!=len(item)\n",
    "        return [check(item, pattern) for item in queries]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def camelMatch(self, queries: List[str], pattern: str) -> List[bool]:\n",
    "        def check(qu,pa):\n",
    "            lm = len(qu)\n",
    "            i = 0\n",
    "            ln = len(pa)\n",
    "            j = 0\n",
    "            while i < lm and j < ln:\n",
    "                print(i, j, qu[i], pa[j])\n",
    "                if qu[i] == pa[j]:\n",
    "                    i += 1\n",
    "                    j += 1\n",
    "                elif qu[i] != pa[j] and qu[i].islower():\n",
    "                    i += 1\n",
    "                elif qu[i] != pa[j] and qu[i].upper():\n",
    "                    return False\n",
    "            if j != ln:\n",
    "                return False\n",
    "            else:\n",
    "                print(i, qu[i:])\n",
    "                for x in qu[i:]:\n",
    "                    if x.isupper():\n",
    "                        return False\n",
    "            return True\n",
    "        # print([check(q, pattern) for q in queries])\n",
    "        return [check(q, pattern) for q in queries]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def camelMatch(self, queries: List[str], pattern: str) -> List[bool]:\n",
    "        lenp = len(pattern)\n",
    "        def check(s):\n",
    "            ls, lp, lens = 0, 0, len(s)\n",
    "            while ls < lens and lp < lenp:\n",
    "                if s[ls] == pattern[lp]: lp += 1\n",
    "                elif s[ls].isupper(): return False\n",
    "                ls += 1\n",
    "            return lp == lenp and len(list(filter(lambda x: x.isupper(), s[ls:]))) == 0\n",
    "\n",
    "        return [check(s) for s in queries]\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def camelMatch(self, queries: List[str], pattern: str) -> List[bool]:\n",
    "        lenp = len(pattern)\n",
    "        def check(s):\n",
    "            ls, lp, lens = 0, 0, len(s)\n",
    "            while ls < lens and lp < lenp:\n",
    "                if s[ls] == pattern[lp]: lp += 1\n",
    "                elif s[ls].isupper(): return False\n",
    "                ls += 1\n",
    "            return lp == lenp and len(list(filter(lambda x: x.isupper(), s[ls:]))) == 0\n",
    "\n",
    "        return [check(s) for s in queries]\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def camelMatch(self, queries: List[str], pattern: str) -> List[bool]:\n",
    "        def check(item, pattern):\n",
    "            i , j = 0 , 0\n",
    "            while j < len(pattern):\n",
    "                while i < len(item) and item[i] != pattern[j] and item[i].islower():\n",
    "                    #跳过不相同的item小写部分\n",
    "                    i += 1\n",
    "                if i == len(item) or item[i] != pattern[j]:\n",
    "                  #如果到字符串末尾,或大写字母不匹配\n",
    "                    return False\n",
    "                i += 1\n",
    "                j += 1\n",
    "\n",
    "            while i < len(item) and item[i].islower():\n",
    "                #跳过末尾的item小写部分\n",
    "                i += 1\n",
    "            return i == len(item)#如果在跳过末尾小写部分时遇到大写,则i!=len(item)\n",
    "        return [check(item, pattern) for item in queries]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def camelMatch(self, queries: List[str], pattern: str) -> List[bool]:\n",
    "        lenp = len(pattern)\n",
    "        def check(s):\n",
    "            ls, lp, lens = 0, 0, len(s)\n",
    "            while ls < lens and lp < lenp:\n",
    "                if s[ls] == pattern[lp]: lp += 1\n",
    "                elif s[ls].isupper(): return False\n",
    "                ls += 1\n",
    "            return lp == lenp and len(list(filter(lambda x: x.isupper(), s[ls:]))) == 0\n",
    "\n",
    "        return [check(s) for s in queries]\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def camelMatch(self, queries: List[str], pattern: str) -> List[bool]:\n",
    "        def check(qu,pa):\n",
    "            lm = len(qu)\n",
    "            i = 0\n",
    "            ln = len(pa)\n",
    "            j = 0\n",
    "            while i < lm and j < ln:\n",
    "                print(i, j, qu[i], pa[j])\n",
    "                if qu[i] == pa[j]:\n",
    "                    i += 1\n",
    "                    j += 1\n",
    "                elif qu[i] != pa[j] and qu[i].islower():\n",
    "                    i += 1\n",
    "                elif qu[i] != pa[j] and qu[i].upper():\n",
    "                    return False\n",
    "            if j != ln:\n",
    "                return False\n",
    "            else:\n",
    "                for x in qu[i:]:\n",
    "                    if x.isupper():\n",
    "                        return False\n",
    "            return True\n",
    "        # print([check(q, pattern) for q in queries])\n",
    "        return [check(q, pattern) for q in queries]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Trie:\n",
    "    def __init__(self,):\n",
    "        self.children = dict()\n",
    "        self.isEnd = False\n",
    "    \n",
    "    def insert(self, word: str) -> None:\n",
    "        cur = self\n",
    "        for ch in word:\n",
    "            if ch not in cur.children:\n",
    "                cur.children[ch] = Trie()\n",
    "            cur = cur.children[ch]\n",
    "        cur.isEnd = True\n",
    "\n",
    "    def search(self, word: str) -> bool:\n",
    "        cur = self\n",
    "        for ch in word:\n",
    "            if not ch.isupper():\n",
    "                # 不匹配的小写字母跳过，这个操作很巧妙，不会移动cur\n",
    "                if ch not in cur.children:\n",
    "                    continue\n",
    "            else:\n",
    "                if ch not in cur.children:\n",
    "                    return False\n",
    "            cur = cur.children[ch]\n",
    "        return cur.isEnd\n",
    "\n",
    "class Solution:\n",
    "    def camelMatch(self, queries: List[str], pattern: str) -> List[bool]:\n",
    "        # lenp = len(pattern)\n",
    "        # def check(s):\n",
    "        #     ls, lp, lens = 0, 0, len(s)\n",
    "        #     while ls < lens and lp < lenp:\n",
    "        #         if s[ls] == pattern[lp]: lp += 1\n",
    "        #         elif s[ls].isupper(): return False\n",
    "        #         ls += 1\n",
    "        #     return lp == lenp and len(list(filter(lambda x: x.isupper(), s[ls:]))) == 0\n",
    "        # return [check(s) for s in queries]\n",
    "        dict_tree = Trie()\n",
    "        dict_tree.insert(pattern)\n",
    "        return [dict_tree.search(query) for query in queries]\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def canIWin(self, maxChoosableInteger: int, desiredTotal: int) -> bool:\n",
    "        max_sum = maxChoosableInteger*(maxChoosableInteger+1)//2\n",
    "        if max_sum < desiredTotal:\n",
    "            return False\n",
    "        elif max_sum == desiredTotal:\n",
    "            return (maxChoosableInteger % 2 == 1)\n",
    "\n",
    "        if maxChoosableInteger >= desiredTotal:\n",
    "            return True\n",
    "\n",
    "        bit_mask = 1 << maxChoosableInteger\n",
    "        self.record = {}\n",
    "\n",
    "        return self.checkWin(maxChoosableInteger, bit_mask, desiredTotal)\n",
    "\n",
    "    def checkWin(self, max_num, bit_mask, remain_sum):\n",
    "\n",
    "        if bit_mask in self.record:\n",
    "            return self.record[bit_mask]\n",
    "\n",
    "        for i in range(max_num):\n",
    "            if (1 & (bit_mask >> i)) != 0:\n",
    "                continue\n",
    "\n",
    "            n = i+1\n",
    "            if (n >= remain_sum) or (self.checkWin(max_num, bit_mask | (1 << i), remain_sum-n) is False):\n",
    "                self.record[bit_mask] = True\n",
    "                return True\n",
    "\n",
    "        self.record[bit_mask] = False\n",
    "        return False\n",
    "\n",
    "\n",
    "            \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def canIWin(self, maxChoosableInteger: int, desiredTotal: int) -> bool:\n",
    "        m = maxChoosableInteger * (maxChoosableInteger + 1) // 2\n",
    "        if desiredTotal > m:\n",
    "            return False\n",
    "        elif desiredTotal == m:\n",
    "            return maxChoosableInteger % 2 == 1\n",
    "        if desiredTotal == 0:\n",
    "            return True\n",
    "        WIN = 1\n",
    "        LOSE = -1\n",
    "        PENDING = 0\n",
    "        bits = [1 << i for i in range(maxChoosableInteger)]\n",
    "        n = 1 << maxChoosableInteger\n",
    "        a = [PENDING] * n\n",
    "\n",
    "        def check(flags, s):\n",
    "            if s < desiredTotal:\n",
    "                a[flags] = LOSE\n",
    "                for i in range(maxChoosableInteger):\n",
    "                    if flags & bits[i] == 0:\n",
    "                        f = flags + bits[i]\n",
    "                        if a[f] == PENDING:\n",
    "                            check(f, s + i + 1)\n",
    "                        if a[f] == LOSE:\n",
    "                            a[flags] = WIN\n",
    "                            break\n",
    "            else:\n",
    "                a[flags] = LOSE\n",
    "        check(0, 0)\n",
    "        return a[0] == WIN"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def canIWin(self, maxChoosableInteger: int, desiredTotal: int) -> bool:\n",
    "        seen = {}\n",
    "\n",
    "        def canWin(choices, remainder):\n",
    "            if choices[-1] >= remainder:\n",
    "                return True\n",
    "            # keep track of all the values, if we have visited this before we are just going to return it\n",
    "            selected = tuple(choices)\n",
    "            if selected in seen:\n",
    "                return seen[selected]\n",
    "            # your opponent needs to lose for you to win\n",
    "            for i in range(len(choices)):\n",
    "                if not canWin(choices[:i] + choices[i+1:], remainder - choices[i]):\n",
    "                    seen[selected] = True\n",
    "                    return True\n",
    "\n",
    "            # if all have gone through, we know we have lost the game\n",
    "            seen[selected] = False\n",
    "            return False\n",
    "\n",
    "        totalSum = (maxChoosableInteger + 1) * maxChoosableInteger / 2\n",
    "\n",
    "        # check if we can actually play the game, else return false\n",
    "        if totalSum < desiredTotal:\n",
    "            return False\n",
    "        # it's a matter of whether you have an odd or even number\n",
    "        if totalSum == desiredTotal:\n",
    "            return maxChoosableInteger % 2 == 1\n",
    "\n",
    "        choice = list(range(1, maxChoosableInteger + 1))\n",
    "        return canWin(choice, desiredTotal)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def canIWin(self, maxChoosableInteger: int, desiredTotal: int) -> bool:\n",
    "        if (maxChoosableInteger + 1) * maxChoosableInteger < 2 * desiredTotal:\n",
    "            return False\n",
    "\n",
    "        nums = list(range(1, maxChoosableInteger+1))\n",
    "        @lru_cache(None)\n",
    "        def check(flag, target):\n",
    "            right = maxChoosableInteger-1\n",
    "            while flag[right] == \"0\":\n",
    "                right -= 1\n",
    "            \n",
    "            left = 0\n",
    "            while flag[left] == \"0\":\n",
    "                left += 1\n",
    "    \n",
    "            if target <= nums[right]:\n",
    "                return True\n",
    "\n",
    "            if target <= nums[right] + nums[left]:\n",
    "                return False\n",
    "\n",
    "            ans = False\n",
    "            for i in range(right+1):\n",
    "                if flag[i] == \"1\":\n",
    "                    ans |= not check(flag[:i] + \"0\" + flag[i+1:], target-nums[i])\n",
    "                if ans: return True\n",
    "            return False\n",
    "            \n",
    "        return check(\"1\"*maxChoosableInteger, desiredTotal)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def canMakePaliQueries(self, s: str, queries: List[List[int]]) -> List[bool]:\n",
    "        size = len(s)\n",
    "        state = []\n",
    "        for i in range(26):\n",
    "            state.append([0] + [0 for _ in range(size)])\n",
    "\n",
    "        for idx, i in enumerate(s):\n",
    "            for char in range(26):\n",
    "                state[char][idx+1] = state[char][idx]\n",
    "                if char == ord(i) - ord('a'):\n",
    "                    state[char][idx+1] += 1\n",
    "\n",
    "        res = []\n",
    "        for l, r, k in queries:\n",
    "            cnt = 0\n",
    "            for i in range(26):\n",
    "                cnt += (state[i][r+1] - state[i][l]) % 2\n",
    "            res.append(cnt // 2 <= k)\n",
    "        return res\n",
    "\n",
    "            \n",
    "\n",
    "    def check(self, s: str):\n",
    "        cnt = {}\n",
    "        for i in s:\n",
    "            if i not in cnt:\n",
    "                cnt[i] = 0\n",
    "            cnt[i] += 1\n",
    "        res = 0\n",
    "        for k, v in cnt.items():\n",
    "            if v % 2 == 0:\n",
    "                continue\n",
    "            res += 1\n",
    "        return res//2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def canMakePaliQueries(self, s: str, queries: List[List[int]]) -> List[bool]:\n",
    "        res=[]\n",
    "        n=len(s)\n",
    "        row=[0]*26\n",
    "        s_list=[row]\n",
    "        begin=ord('a')\n",
    "        for i in range(n):\n",
    "            tmp_row=s_list[i].copy()\n",
    "            tmp_row[ord(s[i])-begin]+=1\n",
    "            s_list.append(tmp_row)\n",
    "        # print(s_list)\n",
    "\n",
    "        for i,j,k in queries:\n",
    "            delta_list=[s_list[j+1][nnnn]-s_list[i][nnnn] for nnnn in range(26)]\n",
    "            res.append(self.checkPal(delta_list,k,j-i+1))\n",
    "        \n",
    "        return res\n",
    "\n",
    "    def checkPal(self, s_list,k,n):\n",
    "        nn=n//2\n",
    "        if nn<=k:\n",
    "            return True\n",
    "\n",
    "\n",
    "        un_match_count=0\n",
    "        for v in s_list:\n",
    "            un_match_count+=v%2\n",
    "        \n",
    "        if un_match_count//2<=k:\n",
    "            return True\n",
    "        else:\n",
    "            return False\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def canMakePaliQueries(self, s: str, queries: List[List[int]]) -> List[bool]:\n",
    "        check = [[] for _ in range(26)]\n",
    "        for i in range(26):\n",
    "            check[i].append(0)\n",
    "        \n",
    "        for c in s:\n",
    "            for i in range(26):\n",
    "                if ord(c) - 97 == i:\n",
    "                    check[i].append(check[i][-1] + 1)\n",
    "                else:\n",
    "                    check[i].append(check[i][-1])\n",
    "\n",
    "        ans = []\n",
    "        for query in queries:\n",
    "            left, right, k = query[0], query[1], query[2]\n",
    "            odds = 0\n",
    "            for i in range(26):\n",
    "                if (check[i][right+1] - check[i][left]) % 2 == 1:\n",
    "                    odds += 1\n",
    "            \n",
    "            if odds // 2 <= k:\n",
    "                ans.append(True)\n",
    "            else:\n",
    "                ans.append(False)\n",
    "        \n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def canMakePaliQueries(self, s: str, queries: List[List[int]]) -> List[bool]:\n",
    "        # 集合 + 前缀和的思想\n",
    "        # a[k]记录字符串s[0:k]的字符出现情况（这里只需要记录单数情况，因为偶数总能重排成回文结构\n",
    "        a = [set() for _ in range(len(s) + 1)] \n",
    "        d = set()\n",
    "        for i, c in enumerate(s, 1):\n",
    "            if c in d:\n",
    "                d.remove(c)\n",
    "            else:\n",
    "                d.add(c)\n",
    "            a[i] = d.copy()\n",
    "        \n",
    "        def check(l: int, r: int, change: int):\n",
    "            res = a[l].union(a[r + 1]) - a[l].intersection(a[r+1])\n",
    "            if change >= (len(res) // 2):\n",
    "                return True\n",
    "            return False\n",
    "        \n",
    "        return [check(left, right, k) for left, right, k in queries]\n",
    "            \n",
    "            "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def canMakePaliQueries(self, s: str, queries: List[List[int]]) -> List[bool]:\n",
    "\n",
    "        record = dict.fromkeys(s)\n",
    "        for c in record:\n",
    "            record[c] = [0 for _ in range(len(s))]\n",
    "        for i in range(len(s)):\n",
    "            record[s[i]][i] = 1\n",
    "        \n",
    "        for c in record:\n",
    "            for i in range(1, len(s)):\n",
    "                record[c][i] = record[c][i]+record[c][i-1]\n",
    "\n",
    "            \n",
    "        def check(l,r,k):\n",
    "            \n",
    "            n_odd = 0\n",
    "            for c in record:\n",
    "                if l>0:\n",
    "                    if (record[c][r] - record[c][l-1])%2==1:\n",
    "                        n_odd += 1\n",
    "                else:\n",
    "                    if record[c][r]%2==1:\n",
    "                        n_odd += 1\n",
    "                           \n",
    "            if n_odd > 2*k + 1:\n",
    "                return False\n",
    "            else:\n",
    "                return True\n",
    "\n",
    "        return [check(ind[0],ind[1],ind[2]) for ind in queries]\n",
    "                    \n",
    "            "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def canEat(self, candiesCount: List[int], queries: List[List[int]]) -> List[bool]:\n",
    "        \n",
    "        n = len(candiesCount)\n",
    "        pre = [0]\n",
    "        for num in candiesCount:\n",
    "            pre.append(pre[-1] + num)\n",
    "        print(pre)\n",
    "\n",
    "        def check(idx, t, k):\n",
    "            # 0-i-1最少需要消耗多少？pre[idx] - k + 1\n",
    "            # 0-i-1至多消耗多少？pre[idx + 1] - 1\n",
    "            return t <= pre[idx + 1] - 1 and k * t >= pre[idx] - k + 1\n",
    "        \n",
    "        ans = []\n",
    "        for idx, t, k in queries:\n",
    "            ans.append(check(idx, t, k))\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def canEat(self, candiesCount: List[int], queries: List[List[int]]) -> List[bool]:\n",
    "        n = len(candiesCount)\n",
    "        pre = [0] * (n + 1)\n",
    "        for i in range(1, n + 1):\n",
    "            pre[i] = pre[i-1] + candiesCount[i-1]\n",
    "        \n",
    "\n",
    "        def check(idx, t, k):\n",
    "            # 要第t天吃到种类为idx的糖\n",
    "            # 那么在t-1天最少要吃 pre[idx] - k + 1个糖\n",
    "            # 最多在t-1天吃掉pre[idx + 1] - 1个糖\n",
    "\n",
    "            return t * k >= pre[idx] - k + 1 and t <= pre[idx + 1] - 1\n",
    "        \n",
    "        ans = []\n",
    "        for idx, t, k in queries:\n",
    "            ans.append(check(idx, t, k))\n",
    "\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def candyCrush(self, board: List[List[int]]) -> List[List[int]]:\n",
    "        def check():\n",
    "            state = [[0] * n for _ in range(m)]\n",
    "            signal = 0\n",
    "            for i in range(m):\n",
    "                j = 0\n",
    "                while j < n - 2:\n",
    "                    cur = board[i][j]\n",
    "                    if cur != 0 and cur == board[i][j + 1] and cur == board[i][j + 2]:\n",
    "                        signal = 1\n",
    "                        state[i][j:j+3] = [1]*3\n",
    "                        j += 2\n",
    "                        while j + 1 < n and board[i][j + 1] == board[i][j]:\n",
    "                            state[i][j + 1] = 1\n",
    "                            j += 1\n",
    "                    j += 1\n",
    "            for j in range(n):\n",
    "                i = m - 1\n",
    "                while i >= 2:\n",
    "                    cur = board[i][j]\n",
    "                    if cur == 0:\n",
    "                        break\n",
    "                    if cur == board[i - 1][j] and cur == board[i - 2][j]:\n",
    "                        signal = 1\n",
    "                        for x in range(i, i - 3, -1):\n",
    "                            state[x][j] = 1\n",
    "                        i -= 2\n",
    "                        while i >= 1 and board[i - 1][j] == board[i][j]:\n",
    "                            state[i - 1][j] = 1\n",
    "                            i -= 1\n",
    "                    i -= 1\n",
    "            return state, signal\n",
    "        \n",
    "        def revise(state):\n",
    "            for j in range(n):\n",
    "                i = m - 1\n",
    "                pos = m - 1\n",
    "                while pos >= 0:\n",
    "                    if state[pos][j] != 1:\n",
    "                        board[i][j] = board[pos][j]\n",
    "                        i -= 1\n",
    "                    pos -= 1\n",
    "                while i >= 0 and board[i][j] != 0:\n",
    "                    board[i][j] = 0\n",
    "                    i -= 1\n",
    "        \n",
    "        m, n = len(board), len(board[0])\n",
    "        while True:\n",
    "            sta, sig = check()\n",
    "            if sig == 0:\n",
    "                return board\n",
    "            revise(sta)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    '''\n",
    "    Repeatedly until the board is stable:\n",
    "        Find the candies to crush:\n",
    "            Iterate through the board and for each cell, check if it starts a row or column of 3 candies of the same type.\n",
    "            Mark the candies to crush in-place by setting their value to negative.\n",
    "        Crush and drop the candies:\n",
    "            Iterate through the board by ascending column and descending row.\n",
    "            Keep track of the number of empty cells in the current column and drop the candies above by that number.\n",
    "    Time complexity: O(mn * mn) (loose upper bound). Space complexity: O(1).\n",
    "    '''\n",
    "    def candyCrush(self, board: List[List[int]]) -> List[List[int]]:\n",
    "        m, n = len(board), len(board[0])\n",
    "        while True:\n",
    "            stable = True\n",
    "            for i in range(m):\n",
    "                for j in range(n):\n",
    "                    if board[i][j] == 0:\n",
    "                        continue\n",
    "                    if i + 2 < m and abs(board[i][j]) == abs(board[i + 1][j]) == abs(board[i + 2][j]):\n",
    "                        stable = False\n",
    "                        board[i][j] = board[i + 1][j] = board[i + 2][j] = -abs(board[i][j])\n",
    "                    if j + 2 < n and abs(board[i][j]) == abs(board[i][j + 1]) == abs(board[i][j + 2]):\n",
    "                        stable = False\n",
    "                        board[i][j] = board[i][j + 1] = board[i][j + 2] = -abs(board[i][j])\n",
    "            \n",
    "            if stable:\n",
    "                return board\n",
    "                \n",
    "            for j in range(n):\n",
    "                numEmpty = 0\n",
    "                for i in range(m-1, -1, -1):\n",
    "                    if board[i][j] <= 0:\n",
    "                        board[i][j] = 0\n",
    "                        numEmpty += 1\n",
    "                    else:\n",
    "                        board[i][j], board[i+numEmpty][j] = board[i+numEmpty][j], board[i][j]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# class Solution:\n",
    "#     def candyCrush(self, board: List[List[int]]) -> List[List[int]]:\n",
    "#         def in_board(i, j):\n",
    "#             if i < len(board) and i >= 0 and j < len(board[0]) and j >= 0:\n",
    "#                 return True\n",
    "#             return False\n",
    "        \n",
    "#         def check_adjacent(board, i, j):\n",
    "#             dirs = [(1,0), (-1,0), (0,1), (0,-1)]\n",
    "#             cur_val = board[i][j]\n",
    "#             board[i][j] = 0\n",
    "#             temp_list = []\n",
    "#             for dir in dirs:\n",
    "#                 cur_i = i + dir[0]\n",
    "#                 cur_j = j + dir[1]\n",
    "#                 if in_board(cur_i, cur_j) and board[cur_i][cur_j] == cur_val:\n",
    "#                     temp_list = temp_list + check_adjacent(board, cur_i, cur_j)\n",
    "#             temp_list.append((i, j))\n",
    "#             return temp_list\n",
    "        \n",
    "#         def drop_board(): # todo update algorithm if possible\n",
    "#             for j in range(len(board[0])-1, -1, -1):\n",
    "#                 for i in range(len(board)-1, -1, -1):\n",
    "#                     if board[i][j] == 0:\n",
    "#                         board[0][j] = 0\n",
    "#                         for k in range(1, i + 1):\n",
    "#                             board[k][j] = board[k-1][j]\n",
    "#         def print_board():\n",
    "#             for i in range(len(board)):\n",
    "#                 for j in range(len(board[0])):\n",
    "#                     print(board[i][j], end=\" \")\n",
    "#                 print(\"\")\n",
    "\n",
    "        \n",
    "#         while True:\n",
    "#             prev_board = copy.deepcopy(board)\n",
    "#             # check\n",
    "#             for i in range(len(board)):\n",
    "#                 for j in range(len(board[0])):\n",
    "#                     if board[i][j] != 0:\n",
    "#                         temp_list = check_adjacent(board[:][:], i, j)\n",
    "#                         print(f\"temp_list : {temp_list}\")\n",
    "#                         if len(temp_list) >= 3:\n",
    "#                             for loc in temp_list:\n",
    "#                                 board[loc[0]][loc[1]] = 0\n",
    "#             print(\"board before dropping\")\n",
    "#             print_board()\n",
    "#             # drop\n",
    "#             drop_board()\n",
    "#             print(\"board after dropping\")\n",
    "#             print_board()\n",
    "\n",
    "#             if prev_board == board:\n",
    "#                 break\n",
    "#         return board\n",
    "        \n",
    "\n",
    "class Solution(object):\n",
    "    def candyCrush(self, board):\n",
    "        R, C = len(board), len(board[0])\n",
    "        todo = False\n",
    "\n",
    "        for r in range(R):\n",
    "            for c in range(C-2):\n",
    "                if abs(board[r][c]) == abs(board[r][c+1]) == abs(board[r][c+2]) != 0:\n",
    "                    board[r][c] = board[r][c+1] = board[r][c+2] = -abs(board[r][c])\n",
    "                    todo = True\n",
    "\n",
    "        for r in range(R-2):\n",
    "            for c in range(C):\n",
    "                if abs(board[r][c]) == abs(board[r+1][c]) == abs(board[r+2][c]) != 0:\n",
    "                    board[r][c] = board[r+1][c] = board[r+2][c] = -abs(board[r][c])\n",
    "                    todo = True\n",
    "\n",
    "        for c in range(C):\n",
    "            wr = R-1\n",
    "            for r in range(R-1, -1, -1):\n",
    "                if board[r][c] > 0:\n",
    "                    board[wr][c] = board[r][c]\n",
    "                    wr -= 1\n",
    "            for wr in range(wr, -1, -1):\n",
    "                board[wr][c] = 0\n",
    "\n",
    "        return self.candyCrush(board) if todo else board"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def candyCrush(self, board: List[List[int]]) -> List[List[int]]:\n",
    "        m = len(board)\n",
    "        n = len(board[0])\n",
    "        def check(board_):\n",
    "            # 检查是存在能够消除的格子并标记\n",
    "            flags = [[0]*n for _ in range(m)]\n",
    "            f = False\n",
    "            # 先检查行\n",
    "            for i in range(m):\n",
    "                for j in range(n-2):\n",
    "                    if board_[i][j]==board_[i][j+1]==board_[i][j+2]!=0:\n",
    "                        flags[i][j]=1\n",
    "                        flags[i][j+1]=1\n",
    "                        flags[i][j+2]=1\n",
    "                        f = True\n",
    "            # 检查列\n",
    "            for j in range(n):\n",
    "                for i in range(m-2):\n",
    "                    if board_[i][j]==board_[i+1][j]==board_[i+2][j]!=0:\n",
    "                        flags[i][j]=1\n",
    "                        flags[i+1][j]=1\n",
    "                        flags[i+2][j]=1\n",
    "                        f = True\n",
    "            return f, flags\n",
    "        \n",
    "        def ruin(board_, flags):\n",
    "            for j in range(n):\n",
    "                # 按列写回糖果\n",
    "                read = m-1\n",
    "                write = m-1\n",
    "                while write>=0:\n",
    "                    while read >= 0 and flags[read][j]==1:\n",
    "                        read -= 1\n",
    "                    \n",
    "                    if read < 0:\n",
    "                        board_[write][j] = 0\n",
    "                    else:\n",
    "                        board_[write][j] = board_[read][j]\n",
    "                    write -= 1\n",
    "                    read -= 1\n",
    "            return board_\n",
    "\n",
    "        while True:\n",
    "            f, flag = check(board)\n",
    "            if f:\n",
    "                board = ruin(board, flag)\n",
    "            else:\n",
    "                return board\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def candyCrush(self, board: List[List[int]]) -> List[List[int]]:\n",
    "        row = len(board)\n",
    "        col = len(board[0])\n",
    "        stable = None\n",
    "        while not stable:\n",
    "            stable = True\n",
    "            # check column axis lines\n",
    "            for r in range(row):\n",
    "                for c in range(col-2):\n",
    "                    if abs(board[r][c]) == abs(board[r][c+1]) == abs(board[r][c+2]) != 0:\n",
    "                        board[r][c] = board[r][c+1] = board[r][c+2] = -abs(board[r][c])\n",
    "                        stable = False\n",
    "            # check row axis lines\n",
    "            for r in range(row-2):\n",
    "                for c in range(col):\n",
    "                    if abs(board[r][c]) == abs(board[r+1][c]) == abs(board[r+2][c]) != 0:\n",
    "                        board[r][c] = board[r+1][c] = board[r+2][c] = -abs(board[r][c])\n",
    "                        stable = False\n",
    "            # for each column, from bottom to top eliminate the negative values\n",
    "            for c in range(col):\n",
    "                row_ptr = row - 1\n",
    "                for r in range(row-1, -1, -1):\n",
    "                    if board[r][c] > 0:\n",
    "                        board[row_ptr][c] = board[r][c]\n",
    "                        row_ptr -= 1\n",
    "                for remain in range(row_ptr, -1, -1):\n",
    "                    board[remain][c] = 0\n",
    "        return board"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def candyCrush(self, board: List[List[int]]) -> List[List[int]]:\n",
    "        def check():\n",
    "            signal = 0\n",
    "            for i in range(m):\n",
    "                j = 0\n",
    "                while j < n - 2:\n",
    "                    cur = board[i][j]\n",
    "                    if cur != 0 and cur == board[i][j + 1] and cur == board[i][j + 2]:\n",
    "                        signal = 1\n",
    "                        state[i][j:j+3] = [1]*3\n",
    "                        j += 2\n",
    "                        while j + 1 < n and board[i][j + 1] == board[i][j]:\n",
    "                            state[i][j + 1] = 1\n",
    "                            j += 1\n",
    "                    j += 1\n",
    "            for j in range(n):\n",
    "                i = m - 1\n",
    "                while i >= 2:\n",
    "                    cur = board[i][j]\n",
    "                    if cur == 0:\n",
    "                        break\n",
    "                    if cur == board[i - 1][j] and cur == board[i - 2][j]:\n",
    "                        signal = 1\n",
    "                        for x in range(i, i - 3, -1):\n",
    "                            state[x][j] = 1\n",
    "                        i -= 2\n",
    "                        while i >= 1 and board[i - 1][j] == board[i][j]:\n",
    "                            state[i - 1][j] = 1\n",
    "                            i -= 1\n",
    "                    i -= 1\n",
    "            return state, signal\n",
    "        \n",
    "        def revise(state):\n",
    "            for j in range(n):\n",
    "                i = m - 1\n",
    "                pos = m - 1\n",
    "                while pos >= 0:\n",
    "                    if state[pos][j] != 1:\n",
    "                        board[i][j] = board[pos][j]\n",
    "                        i -= 1\n",
    "                    state[pos][j] = 0\n",
    "                    pos -= 1\n",
    "                while i >= 0 and board[i][j] != 0:\n",
    "                    board[i][j] = 0\n",
    "                    i -= 1\n",
    "        \n",
    "        m, n = len(board), len(board[0])\n",
    "        state = [[0] * n for _ in range(m)]\n",
    "        while True:\n",
    "            sta, sig = check()\n",
    "            if sig == 0:\n",
    "                return board\n",
    "            revise(sta)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    '''\n",
    "    Repeatedly until the board is stable:\n",
    "        Find the candies to crush:\n",
    "            Iterate through the board and for each cell, check if it starts a row or column of 3 candies of the same type.\n",
    "            Mark the candies to crush in-place by setting their value to negative.\n",
    "        Crush and drop the candies:\n",
    "            Iterate through the board by ascending column and descending row.\n",
    "            Keep track of the number of empty cells in the current column and drop the candies above by that number.\n",
    "    Time complexity: O(mn * mn) (loose upper bound). Space complexity: O(1).\n",
    "    '''\n",
    "    def candyCrush(self, board: List[List[int]]) -> List[List[int]]:\n",
    "        m, n = len(board), len(board[0])\n",
    "        while True:\n",
    "            stable = True\n",
    "            for i in range(m):\n",
    "                for j in range(n):\n",
    "                    if board[i][j] == 0:\n",
    "                        continue\n",
    "                    if i + 2 < m and abs(board[i][j]) == abs(board[i + 1][j]) == abs(board[i + 2][j]):\n",
    "                        stable = False\n",
    "                        board[i][j] = board[i + 1][j] = board[i + 2][j] = -abs(board[i][j])\n",
    "                    if j + 2 < n and abs(board[i][j]) == abs(board[i][j + 1]) == abs(board[i][j + 2]):\n",
    "                        stable = False\n",
    "                        board[i][j] = board[i][j + 1] = board[i][j + 2] = -abs(board[i][j])\n",
    "            \n",
    "            if stable:\n",
    "                break\n",
    "                \n",
    "            for j in range(n):\n",
    "                numEmpty = 0\n",
    "                for i in range(m-1, -1, -1):\n",
    "                    if board[i][j] <= 0:\n",
    "                        board[i][j] = 0\n",
    "                        numEmpty += 1\n",
    "                    else:\n",
    "                        board[i][j], board[i+numEmpty][j] = board[i+numEmpty][j], board[i][j]\n",
    "        return board"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def candyCrush(self, board: List[List[int]]) -> List[List[int]]:\n",
    "        m, n = len(board), len(board[0])\n",
    "        def crush():\n",
    "            cnt = 0\n",
    "            for i in range(m):\n",
    "                for j in range(n):\n",
    "                    if i >= 2 and abs(board[i-2][j]) == abs(board[i-1][j]) == abs(board[i][j]) != 0:\n",
    "                        c = abs(board[i][j])\n",
    "                        board[i-2][j] = board[i-1][j] = board[i][j] = - c\n",
    "                        cnt += 1\n",
    "                    if j >= 2 and abs(board[i][j-2]) == abs(board[i][j-1]) == abs(board[i][j]) != 0:\n",
    "                        c = abs(board[i][j])\n",
    "                        board[i][j-2] = board[i][j-1] = board[i][j] = - c\n",
    "                        cnt += 1\n",
    "            return cnt \n",
    "        def check():\n",
    "            for j in range(n):\n",
    "                to_fill = m-1\n",
    "                for i in range(m-1, -1, -1):\n",
    "                    if board[i][j] > 0:\n",
    "                        tmp = board[i][j]\n",
    "                        board[i][j] = 0\n",
    "                        board[to_fill][j] = abs(tmp)\n",
    "                        to_fill -= 1\n",
    "                    else:\n",
    "                        board[i][j] = 0\n",
    "\n",
    "        # i = 0\n",
    "        while True:\n",
    "            c = crush()\n",
    "            # print(c)\n",
    "            if c == 0:\n",
    "                return board\n",
    "            check()\n",
    "            # i += 1\n",
    "        return board\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def candyCrush(self, board: List[List[int]]) -> List[List[int]]:\n",
    "        R,C= len(board),len(board[0])\n",
    "        #check horizontal same\n",
    "        crashed= False\n",
    "        for r in range(R):\n",
    "            for c in range(C-2):\n",
    "                if abs(board[r][c])==abs(board[r][c+1])==abs(board[r][c+2])!=0:\n",
    "                    board[r][c]=board[r][c+1]=board[r][c+2]=-abs(board[r][c])\n",
    "                    crashed=True\n",
    "        #check vertical same\n",
    "        for c in range(C):\n",
    "            for r in range(R-2):\n",
    "                if abs(board[r][c])==abs(board[r+1][c])==abs(board[r+2][c])!=0:\n",
    "                    board[r][c]=board[r+1][c]=board[r+2][c]=-abs(board[r][c])\n",
    "                    crashed= True\n",
    "\n",
    "        for c in range(C):\n",
    "            write=R-1\n",
    "            for read in range(R-1,-1,-1):\n",
    "                newValue= board[read][c]\n",
    "                board[read][c]=0\n",
    "                if newValue>0:\n",
    "                    board[write][c]= newValue\n",
    "                    write-=1\n",
    "            # for write in range(write,-1,-1):\n",
    "            #     board[write][c]=0\n",
    "        if crashed:\n",
    "            return self.candyCrush(board)\n",
    "        return board\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def candyCrush(self, board: List[List[int]]) -> List[List[int]]:\n",
    "        R,C= len(board),len(board[0])\n",
    "        #check horizontal same\n",
    "        crashed= False\n",
    "        for r in range(R):\n",
    "            for c in range(C-2):\n",
    "                if abs(board[r][c])==abs(board[r][c+1])==abs(board[r][c+2])!=0:\n",
    "                    board[r][c]=board[r][c+1]=board[r][c+2]=-abs(board[r][c])\n",
    "                    crashed=True\n",
    "        #check vertical same\n",
    "        for c in range(C):\n",
    "            for r in range(R-2):\n",
    "                if abs(board[r][c])==abs(board[r+1][c])==abs(board[r+2][c])!=0:\n",
    "                    board[r][c]=board[r+1][c]=board[r+2][c]=-abs(board[r][c])\n",
    "                    crashed= True\n",
    "\n",
    "        for c in range(C):\n",
    "            write=R-1\n",
    "            for read in range(R-1,-1,-1):\n",
    "                if board[read][c]>0:\n",
    "                    board[write][c]= board[read][c]\n",
    "                    write-=1\n",
    "            for write in range(write,-1,-1):\n",
    "                board[write][c]=0\n",
    "        if crashed:\n",
    "            return self.candyCrush(board)\n",
    "        return board\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "from typing import List\n",
    "\n",
    "\"\"\"\n",
    "思路：\n",
    "1. 创建一个形状一样的board，用来记录是否需要消除\n",
    "2. 两轮循环，通过判断左右三个 + 上下三个是否相等来判断是否需要消除，并进行标记\n",
    "3. 根据标记的矩阵进行消除并填补新的元素，方法为不断向上查找第一个不为0的元素，然后将其下移\n",
    "\"\"\"\n",
    "\n",
    "class Solution:\n",
    "    def candyCrush(self, board: List[List[int]]) -> List[List[int]]:\n",
    "        m, n = len(board), len(board[0])\n",
    "        def check_more2go(board, check):\n",
    "            flag = False\n",
    "            for i in range(1, m-1):\n",
    "                for j in range(0, n):\n",
    "                    # 记得考虑board[i][j]为0的情况\n",
    "                    if board[i][j] == 0:\n",
    "                        continue\n",
    "                    if board[i-1][j] == board[i][j] == board[i+1][j]:\n",
    "                        check[i-1][j] = True\n",
    "                        check[i][j] = True\n",
    "                        check[i+1][j] = True\n",
    "                        flag = True\n",
    "\n",
    "            for i in range(0, m):\n",
    "                for j in range(1, n-1):\n",
    "                    # 记得考虑board[i][j]为0的情况\n",
    "                    if board[i][j] == 0:\n",
    "                        continue\n",
    "                    if board[i][j-1] == board[i][j] == board[i][j+1]:\n",
    "                        check[i][j-1] = True\n",
    "                        check[i][j] = True\n",
    "                        check[i][j+1] = True\n",
    "                        flag = True\n",
    "            return flag\n",
    "\n",
    "        while True:\n",
    "            check = [[False] * n for _ in range(m)]\n",
    "            if not check_more2go(board, check):\n",
    "                return board\n",
    "            print(check)\n",
    "            for i in range(m):\n",
    "                for j in range(n):\n",
    "                    if check[i][j]:\n",
    "                        board[i][j] = 0\n",
    "            print(board)\n",
    "            \n",
    "            # 模拟下坠\n",
    "            for i in range(m-1, -1, -1):\n",
    "                for j in range(n):\n",
    "                    if board[i][j] == 0:\n",
    "                        for k in range(i-1, -1, -1):\n",
    "                            if board[k][j] != 0:\n",
    "                                board[i][j] = board[k][j]\n",
    "                                board[k][j] = 0\n",
    "                                break\n",
    "            print(board)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "from typing import List\n",
    "\n",
    "\"\"\"\n",
    "思路：\n",
    "1. 创建一个形状一样的board，用来记录是否需要消除\n",
    "2. 两轮循环，通过判断左右三个 + 上下三个是否相等来判断是否需要消除，并进行标记\n",
    "3. 根据标记的矩阵进行消除并填补新的元素，方法为不断向上查找第一个不为0的元素，然后将其下移\n",
    "\"\"\"\n",
    "\n",
    "class Solution:\n",
    "    def candyCrush(self, board: List[List[int]]) -> List[List[int]]:\n",
    "        m, n = len(board), len(board[0])\n",
    "        def check_more2go(board, check):\n",
    "            flag = False\n",
    "            for i in range(1, m-1):\n",
    "                for j in range(0, n):\n",
    "                    # 记得考虑board[i][j]为0的情况\n",
    "                    if board[i][j] == 0:\n",
    "                        continue\n",
    "                    if board[i-1][j] == board[i][j] == board[i+1][j]:\n",
    "                        check[i-1][j] = True\n",
    "                        check[i][j] = True\n",
    "                        check[i+1][j] = True\n",
    "                        flag = True\n",
    "\n",
    "            for i in range(0, m):\n",
    "                for j in range(1, n-1):\n",
    "                    # 记得考虑board[i][j]为0的情况\n",
    "                    if board[i][j] == 0:\n",
    "                        continue\n",
    "                    if board[i][j-1] == board[i][j] == board[i][j+1]:\n",
    "                        check[i][j-1] = True\n",
    "                        check[i][j] = True\n",
    "                        check[i][j+1] = True\n",
    "                        flag = True\n",
    "            return flag\n",
    "\n",
    "        while True:\n",
    "            check = [[False] * n for _ in range(m)]\n",
    "            if not check_more2go(board, check):\n",
    "                return board\n",
    "            print(check)\n",
    "            for i in range(m):\n",
    "                for j in range(n):\n",
    "                    if check[i][j]:\n",
    "                        board[i][j] = 0\n",
    "            print(board)\n",
    "            \n",
    "            # 模拟下坠\n",
    "            # 必须从最后一行开始\n",
    "            for i in range(m-1, -1, -1):\n",
    "                for j in range(n):\n",
    "                    if board[i][j] == 0:\n",
    "                        for k in range(i-1, -1, -1):\n",
    "                            if board[k][j] != 0:\n",
    "                                board[i][j] = board[k][j]\n",
    "                                board[k][j] = 0\n",
    "                                break\n",
    "            print(board)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def candyCrush(self, board: List[List[int]]) -> List[List[int]]:\n",
    "        def check():\n",
    "            state = [[0] * n for _ in range(m)]\n",
    "            signal = 0\n",
    "            for i in range(m):\n",
    "                j = 0\n",
    "                while j < n - 2:\n",
    "                    cur = board[i][j]\n",
    "                    if cur != 0 and cur == board[i][j + 1] and cur == board[i][j + 2]:\n",
    "                        signal = 1\n",
    "                        state[i][j:j+3] = [1]*3\n",
    "                        j += 2\n",
    "                        while j + 1 < n and board[i][j + 1] == board[i][j]:\n",
    "                            state[i][j + 1] = 1\n",
    "                            j += 1\n",
    "                    j += 1\n",
    "            for j in range(n):\n",
    "                i = m - 1\n",
    "                while i >= 2:\n",
    "                    cur = board[i][j]\n",
    "                    if cur == 0:\n",
    "                        break\n",
    "                    if cur == board[i - 1][j] and cur == board[i - 2][j]:\n",
    "                        signal = 1\n",
    "                        for x in range(i, i - 3, -1):\n",
    "                            state[x][j] = 1\n",
    "                        i -= 2\n",
    "                        while i >= 1 and board[i - 1][j] == board[i][j]:\n",
    "                            state[i - 1][j] = 1\n",
    "                            i -= 1\n",
    "                    i -= 1\n",
    "            return state, signal\n",
    "        \n",
    "        def revise(state):\n",
    "            for j in range(n):\n",
    "                i = m - 1\n",
    "                pos = m - 1\n",
    "                while pos >= 0:\n",
    "                    if state[pos][j] != 1:\n",
    "                        board[i][j] = board[pos][j]\n",
    "                        i -= 1\n",
    "                    pos -= 1\n",
    "                while i >= 0:\n",
    "                    board[i][j] = 0\n",
    "                    i -= 1\n",
    "        \n",
    "        m, n = len(board), len(board[0])\n",
    "        while True:\n",
    "            sta, sig = check()\n",
    "            if sig == 0:\n",
    "                return board\n",
    "            revise(sta)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def shipWithinDays(self, weights: List[int], days: int) -> int:\n",
    "        weightsPre = [0] * (len(weights) + 1)\n",
    "        for i, w in enumerate(weights, 1):\n",
    "            weightsPre[i] = weightsPre[i - 1] + w\n",
    "        # print('weightsPre: ', weightsPre)\n",
    "        \n",
    "        # limit is the assume ship weight capacity, check under this status, if succeed\n",
    "        def check(m: int) -> bool:\n",
    "            # in days times, shipped all weights\n",
    "            usedDay = 0\n",
    "            shippedWeight = 0\n",
    "            i = 1\n",
    "            while i < len(weightsPre):\n",
    "                if weightsPre[i] - shippedWeight <= m: # can ship today\n",
    "                    i += 1\n",
    "                else: # today no more package\n",
    "                    usedDay += 1\n",
    "                    shippedWeight = weightsPre[i - 1]\n",
    "            # print('m usedDay: ', m, usedDay)\n",
    "            return usedDay < days\n",
    "\n",
    "\n",
    "        \n",
    "        l, r = max(weights), sum(weights)\n",
    "        while l < r:\n",
    "            m = (l + r) >> 1\n",
    "            if check(m):\n",
    "                r = m\n",
    "            else:\n",
    "                l = m + 1\n",
    "        return l\n",
    "\n",
    "\n",
    "\n",
    "            \n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def shipWithinDays(self, weights: List[int], D: int) -> int:\n",
    "        left  = max(weights) \n",
    "        right = sum(weights)\n",
    "        def check(w, weigths, D):\n",
    "            count_d = 0\n",
    "            sum_w = 0\n",
    "            for i in range(len(weights)):\n",
    "                if sum_w+weights[i]>w:\n",
    "                    count_d += 1\n",
    "                    sum_w = 0\n",
    "                sum_w += weights[i]\n",
    "            else:\n",
    "                if sum_w>0:\n",
    "                    count_d += 1\n",
    "            return count_d<=D\n",
    "            \n",
    "\n",
    "        def binsearch(l, r):\n",
    "            if r==l:# 左界结束\n",
    "                return l\n",
    "            if r-l==1: # 右界结束\n",
    "                return l if check(l, weights, D) else r\n",
    "            mid = (l+r)//2\n",
    "            is_check = check(mid, weights, D)\n",
    "            print(mid, is_check)\n",
    "            return binsearch(l, mid) if is_check else binsearch(mid, r)\n",
    "        \n",
    "        return binsearch(left, right)\n",
    "            \n",
    "\n",
    "            \n",
    "\n",
    "        \n",
    "\n",
    "\n",
    "        \n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def shipWithinDays(self, weights: List[int], D: int) -> int:\n",
    "        max_w, sum_w = max(weights), sum(weights)\n",
    "        l, r = max(max_w, sum_w // D), sum_w\n",
    "        while l < r:\n",
    "            mid = (l + r) >> 1\n",
    "            if self.check(weights, mid, D):\n",
    "                r = mid\n",
    "            else:\n",
    "                l = mid + 1\n",
    "        return r\n",
    "\n",
    "    def check(self, ws, t, d):\n",
    "        n = len(ws)\n",
    "        i = cnt = 1\n",
    "        total = ws[0]\n",
    "        while i < n:\n",
    "            while i < n and total + ws[i] <= t:\n",
    "                total += ws[i]\n",
    "                i += 1\n",
    "            total = 0\n",
    "            cnt += 1\n",
    "        return cnt - 1 <= d\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def shipWithinDays(self, weights: List[int], days: int) -> int:\n",
    "        left = max(weights)\n",
    "        right = sum(weights)\n",
    "        while left < right:\n",
    "            mid = (left + right) >> 1\n",
    "            if self.check(weights,mid) <= days:\n",
    "                right = mid\n",
    "            else:\n",
    "                left = mid + 1\n",
    "        return left\n",
    "\n",
    "    def check(self,weights,mid):\n",
    "        d = 1\n",
    "        current = 0\n",
    "        for w in weights:\n",
    "            current += w\n",
    "            if current > mid:\n",
    "                d += 1\n",
    "                current = w\n",
    "        return d"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def shipWithinDays(self, weights: List[int], days: int) -> int:\n",
    "        def check(x:int) -> bool:\n",
    "            cnt = 1\n",
    "            y = 0\n",
    "            for weight in weights:\n",
    "                if y + weight > x:\n",
    "                    y = weight\n",
    "                    cnt += 1\n",
    "                else:\n",
    "                    y += weight\n",
    "            return cnt <= days\n",
    "        l,r = max(weights),sum(weights)\n",
    "        while l < r:\n",
    "            m = (l+r)//2\n",
    "            if check(m):\n",
    "                r = m\n",
    "            else:\n",
    "                l = m + 1\n",
    "        return l\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def shipWithinDays(self, weights: List[int], days: int) -> int:\n",
    "        def check_possi(out):\n",
    "            day_cost = 1\n",
    "            cur = 0\n",
    "            for val in weights:\n",
    "                cur += val\n",
    "                if cur > out:\n",
    "                    day_cost += 1\n",
    "                    cur = val\n",
    "                    if day_cost > days:\n",
    "                        return False\n",
    "            return True\n",
    "\n",
    "        LOWER = max(weights)\n",
    "        UPPER = sum(weights)\n",
    "        out = (LOWER + UPPER) // 2\n",
    "        \n",
    "        while out > LOWER:\n",
    "            if check_possi(out):\n",
    "                UPPER = out\n",
    "            else:\n",
    "                LOWER = out\n",
    "            out = (LOWER + UPPER) // 2\n",
    "\n",
    "        if check_possi(out):\n",
    "            return out\n",
    "        else:\n",
    "            return UPPER\n",
    "\n",
    "\n",
    "        \"\"\"\n",
    "        # DP: O(n^2), exceed time limit\n",
    "\n",
    "        val_dict = {}\n",
    "        l = len(weights)\n",
    "        \n",
    "        def DP(i, days):\n",
    "            if (i, days) in val_dict.keys():\n",
    "                return val_dict[(i, days)]\n",
    "            elif days == 1:\n",
    "                out = sum(weights[i:])\n",
    "            elif days >= l - i:\n",
    "                out = max(weights[i:]) \n",
    "            else:\n",
    "                cur = 0\n",
    "                out = float('inf')\n",
    "                for j in range(i, l-1):\n",
    "                    cur += weights[j]\n",
    "                    out_sub = DP(j+1, days - 1)\n",
    "                    out = min(out, max(out_sub, cur))\n",
    "                    if cur >= out_sub:\n",
    "                        break\n",
    "            val_dict[(i, days)] = out\n",
    "            return out\n",
    "\n",
    "        out = DP(0, days)\n",
    "        print(val_dict)\n",
    "        return out\n",
    "        \"\"\"\n",
    "\n",
    "        \"\"\"\n",
    "        def DP(i, days):\n",
    "            if (i, days) in val_dict.keys():\n",
    "                out = val_dict[(i, days)]\n",
    "            elif days == 1:\n",
    "                out = sum(weights[:i])\n",
    "            elif days >= i:\n",
    "                out = max(weights[:i])\n",
    "            else:\n",
    "                out = float('inf')\n",
    "                for j in range(i-1, 0, -1):\n",
    "                    cur = sum(weights[j:i])\n",
    "                    out_sub = DP(j, days - 1)\n",
    "                    out = min(out, max(cur, out_sub))\n",
    "                    if cur >= out_sub:\n",
    "                        #print(j, i, cur)\n",
    "                        break\n",
    "            val_dict[(i, days)] = out\n",
    "            return out\n",
    "\n",
    "        out = DP(l, days)\n",
    "        #print(val_dict)\n",
    "        return out\n",
    "        \"\"\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def shipWithinDays(self, weights: List[int], days: int) -> int:\n",
    "        r = sum(weights)\n",
    "        l = max(weights)\n",
    "\n",
    "        def check(max_load):\n",
    "            loading = 0\n",
    "            need_days = 1\n",
    "            for i in range(len(weights)):\n",
    "                loading = loading + weights[i]\n",
    "                if loading > max_load:\n",
    "                    loading = weights[i]\n",
    "                    need_days += 1\n",
    "                if need_days > days:\n",
    "                    return False\n",
    "            return True \n",
    "        \n",
    "        while l <= r:\n",
    "            mid = (l+r)//2\n",
    "            if check(mid):\n",
    "                r = mid-1\n",
    "            else:\n",
    "                l = mid+1\n",
    "        return l\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def shipWithinDays(self, weights: List[int], days: int) -> int:\n",
    "        def check(w):\n",
    "            w_left=w\n",
    "            days_left=days-1\n",
    "            for i in range(n):\n",
    "                w_i=weights[i]\n",
    "                if w_left>=w_i:\n",
    "                    w_left=w_left-w_i\n",
    "                elif days_left:\n",
    "                    days_left=days_left-1\n",
    "                    w_left=w-w_i\n",
    "                else:\n",
    "                    w=w+1\n",
    "                    w_left=w_left-w_i\n",
    "                    break\n",
    "            if w_left>=0:\n",
    "                return 1\n",
    "            else:\n",
    "                return 0\n",
    "        w_max=max(weights)\n",
    "        w_ave=ceil(sum(weights)//days)\n",
    "        left=max(w_max,w_ave)\n",
    "        right=sum(weights)\n",
    "        n=len(weights)\n",
    "        while(left<right):\n",
    "            w=(left+right)//2\n",
    "            result=check(w)\n",
    "            if result:\n",
    "                right=w\n",
    "            else:\n",
    "                left=w+1\n",
    "        return left\n",
    "            "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def shipWithinDays(self, weights: List[int], days: int) -> int:\n",
    "        def check(mid):\n",
    "            d = 1\n",
    "            curr_w = 0\n",
    "            for w in weights:\n",
    "                curr_w += w\n",
    "                if curr_w > mid:\n",
    "                    d += 1\n",
    "                    curr_w = w\n",
    "            return d <= days\n",
    "        left = max(weights)\n",
    "        right = sum(weights)\n",
    "        while left <= right:\n",
    "            mid = (right + left) //2\n",
    "            if check(mid):\n",
    "                right = mid - 1\n",
    "            else:\n",
    "                left = mid + 1\n",
    "        return left"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "import math\n",
    "\n",
    "class Solution:\n",
    "    def shipWithinDays(self, weights: List[int], days: int) -> int:\n",
    "        left, right = max(weights), math.ceil(len(weights) / days) * max(weights)\n",
    "        while left < right:\n",
    "            mid = (left + right) // 2\n",
    "            if self.check(weights, days, mid):\n",
    "                right = mid\n",
    "            else:\n",
    "                left = mid + 1\n",
    "        \n",
    "        return left\n",
    "\n",
    "    def check(self, weights: List[int], days: int, load: int) -> bool:\n",
    "        cnt = 1\n",
    "        tot = 0\n",
    "        for n in weights:\n",
    "            tot += n\n",
    "            if tot > load:\n",
    "                cnt += 1\n",
    "                tot = n\n",
    "        if cnt <= days:\n",
    "            return True\n",
    "        else: \n",
    "            return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def shipWithinDays(self, weights: List[int], days: int) -> int:\n",
    "        def check(mid):\n",
    "            day = 1\n",
    "            count = 0\n",
    "            for weight in weights:\n",
    "                if count + weight > mid:\n",
    "                    count = 0\n",
    "                    day += 1\n",
    "                count += weight\n",
    "            return day <= days\n",
    "\n",
    "        left = max(weights) - 1\n",
    "        right = sum(weights) + 1\n",
    "        while left + 1 < right:\n",
    "            mid = (left + right) // 2\n",
    "            print(mid)\n",
    "            if check(mid):\n",
    "                right = mid\n",
    "            else:\n",
    "                left = mid\n",
    "        return right\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def shipWithinDays(self, weights: List[int], days: int) -> int:\n",
    "        tt = sum(weights)\n",
    "        l, r = min(weights), tt\n",
    "        n = len(weights)\n",
    "\n",
    "        def checkOk(num):\n",
    "            day = 0\n",
    "            idx = 0\n",
    "            i = 0\n",
    "\n",
    "            while i < n:\n",
    "                j = i\n",
    "                wei = 0\n",
    "                while j < n and wei + weights[j] <= num:\n",
    "                    wei += weights[j]\n",
    "                    j += 1\n",
    "                day += 1\n",
    "                if day > days:\n",
    "                    return False\n",
    "                \n",
    "                i = j\n",
    "            return True\n",
    "\n",
    "\n",
    "\n",
    "        while l < r:\n",
    "            mid = l + (r-l)//2\n",
    "            if checkOk(mid):\n",
    "                r = mid\n",
    "            else:\n",
    "                l = mid + 1\n",
    "        return r # l = r"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def flipgame(self, fronts: List[int], backs: List[int]) -> int:\n",
    "        len_list = len(fronts)\n",
    "        sumList = fronts + backs\n",
    "        # check num from the smallest number\n",
    "        num = 0\n",
    "        while True:\n",
    "            num += 1\n",
    "            if not num in sumList:\n",
    "                # check if we can end the range\n",
    "                ok = True\n",
    "                for val in sumList:\n",
    "                    if num < val:\n",
    "                        ok = False\n",
    "                        break\n",
    "                if ok:\n",
    "                    break\n",
    "                # continue if num not in list\n",
    "                continue\n",
    "            # check if num is correct\n",
    "            correctNum = True\n",
    "            for cnt in range(len_list):\n",
    "                if fronts[cnt] == backs[cnt] == num:\n",
    "                    correctNum = False\n",
    "                    break\n",
    "            if correctNum:\n",
    "                return num\n",
    "                    \n",
    "        return 0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def canFormArray(self, arr: List[int], pieces: List[List[int]]) -> bool:\n",
    "        def check(v):\n",
    "            for i, x in enumerate(arr):\n",
    "                if x == v[0]:\n",
    "                    for j in range(len(v)):\n",
    "                        if i + j == len(arr) or arr[i + j] != v[j]:\n",
    "                            return False\n",
    "            return p[0] in arr\n",
    "        for p in pieces:\n",
    "            if not check(p):\n",
    "                return False\n",
    "        return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, x):\n",
    "#         self.val = x\n",
    "#         self.left = None\n",
    "#         self.right = None\n",
    "\n",
    "class Solution:\n",
    "\tdef isBalanced(self, root: TreeNode) -> bool:\n",
    "\t\tdef check(root):\n",
    "\t\t\tif not root:\n",
    "\t\t\t\treturn 0\n",
    "\t\t\tleft_check = check(root.left)\n",
    "\t\t\tright_check = check(root.right)\n",
    "\t\t\tif left_check == -1 or right_check == -1 or abs(left_check - right_check) > 1:\n",
    "\t\t\t\treturn -1\n",
    "\t\t\telse:\n",
    "\t\t\t\treturn max(left_check, right_check) + 1\n",
    "\n",
    "\t\treturn check(root) >= 0\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isBalanced(self, root: TreeNode) -> bool:\n",
    "        def checkHeight(root):\n",
    "            if not root: return -1\n",
    "\n",
    "            leftHeight = checkHeight(root.left)\n",
    "            if leftHeight == float('inf'): return float('inf') # 向上传递错误\n",
    "\n",
    "            rightHeight = checkHeight(root.right)\n",
    "            if rightHeight == float('inf'): return float('inf') # 向上传递错误\n",
    "\n",
    "            heightDiff = leftHeight - rightHeight\n",
    "            if abs(heightDiff) > 1:\n",
    "                return float('inf') # 发现错误，把它传回来\n",
    "            else:\n",
    "                return max(leftHeight, rightHeight) + 1\n",
    "\n",
    "        return checkHeight(root) != float('inf')\n",
    "\n",
    "# 作者：腐烂的橘子\n",
    "# 链接：https://leetcode.cn/problems/check-balance-lcci/solutions/185819/di-gui-fang-wen-de-gao-du-python3-by-z1m/\n",
    "# 来源：力扣（LeetCode）\n",
    "# 著作权归作者所有。商业转载请联系作者获得授权，非商业转载请注明出处。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, x):\n",
    "#         self.val = x\n",
    "#         self.left = None\n",
    "#         self.right = None\n",
    "\n",
    "class Solution:\n",
    "    def isBalanced(self, root: TreeNode) -> bool:\n",
    "        height = self.checkHeight(root)\n",
    "        return height >= 0\n",
    "    \n",
    "    def checkHeight(self, root):\n",
    "        if root is None:\n",
    "            return 0\n",
    "        \n",
    "        leftHeight = self.checkHeight(root.left)\n",
    "        if leftHeight < 0:\n",
    "            return -1\n",
    "\n",
    "        rightHeight = self.checkHeight(root.right)\n",
    "        if rightHeight < 0:\n",
    "            return -1\n",
    "\n",
    "        if abs(leftHeight - rightHeight) > 1:\n",
    "            return -1\n",
    "        \n",
    "        return max(leftHeight, rightHeight) + 1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, x):\n",
    "#         self.val = x\n",
    "#         self.left = None\n",
    "#         self.right = None\n",
    "\n",
    "class Solution:\n",
    "\tdef isBalanced(self, root: TreeNode) -> bool:\n",
    "\t\tdef check(root):\n",
    "\t\t\tif not root:\n",
    "\t\t\t\treturn 0\n",
    "\t\t\tleft_check = check(root.left)\n",
    "\t\t\tright_check = check(root.right)\n",
    "\t\t\tif left_check == -1 or right_check == -1 or abs(left_check - right_check) > 1:\n",
    "\t\t\t\treturn -1\n",
    "\t\t\telse:\n",
    "\t\t\t\treturn max(left_check, right_check) + 1\n",
    "\n",
    "\t\treturn check(root) >= 0\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\r\n",
    "# class TreeNode:\r\n",
    "#     def __init__(self, x):\r\n",
    "#         self.val = x\r\n",
    "#         self.left = None\r\n",
    "#         self.right = None\r\n",
    "\r\n",
    "class Solution:\r\n",
    "    def isCompleteTree(self, root: TreeNode) -> bool:\r\n",
    "        if not root: return True\r\n",
    "        # 层序遍历\r\n",
    "        import copy\r\n",
    "        curLayer = [root]\r\n",
    "        preLayer = [root]\r\n",
    "        num = 1\r\n",
    "        judgeLast = False\r\n",
    "        hasNoneLeaf = False\r\n",
    "        while curLayer:\r\n",
    "\r\n",
    "            if len(curLayer) != num:\r\n",
    "                while preLayer:\r\n",
    "                    checkNode = preLayer.pop(0) \r\n",
    "                    if hasNoneLeaf:\r\n",
    "                        if checkNode.left or checkNode.right:\r\n",
    "                            return False\r\n",
    "                    else:\r\n",
    "                        if not checkNode.left:\r\n",
    "                            hasNoneLeaf = True\r\n",
    "                        if hasNoneLeaf and  checkNode.right:\r\n",
    "                            return False\r\n",
    "                        if not checkNode.right:\r\n",
    "                            hasNoneLeaf = True\r\n",
    "                judgeLast = True        \r\n",
    "\r\n",
    "\r\n",
    "            num *= 2 \r\n",
    "            preLayer = copy.deepcopy(curLayer)\r\n",
    "\r\n",
    "            nextLayer = []\r\n",
    "            while curLayer:\r\n",
    "                cur = curLayer.pop(0)\r\n",
    "                if cur.left:\r\n",
    "                    nextLayer.append(cur.left)\r\n",
    "                if cur.right:\r\n",
    "                    nextLayer.append(cur.right)\r\n",
    "            curLayer = nextLayer\r\n",
    "\r\n",
    "            if judgeLast and nextLayer:\r\n",
    "                return False\r\n",
    "        return True\r\n",
    "            \r\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "\n",
    "\n",
    "# class Solution:\n",
    "#     def isCompleteTree(self, root: Optional[TreeNode]) -> bool:\n",
    "#         # 层序遍历，只要出现过空节点，就不能再出现任何非空节点\n",
    "#         q = collections.deque([root])\n",
    "#         # 注意：当前层空节点靠右，但下一层还有节点，也是非完全的\n",
    "#         # 所以设置的是全局变量\n",
    "#         none_flag = False  # 是否出现过空节点\n",
    "#         while q:\n",
    "#             for _ in range(len(q)):\n",
    "#                 curr = q.popleft()\n",
    "#                 if curr==None:\n",
    "#                     none_flag = True\n",
    "#                 else: # 当前非空\n",
    "#                     if none_flag: # 又出现非空节点，则是不完全\n",
    "#                         return False\n",
    "#                     q.append(curr.left)\n",
    "#                     q.append(curr.right)\n",
    "#         return True\n",
    "\n",
    "\n",
    "class Solution(object):\n",
    "    def isCompleteTree(self, root):\n",
    "        # 层序，当标号超出总记录长度时停止（即记录空节点后停止）\n",
    "        nodes = [(root, 1)]\n",
    "        i = 0\n",
    "        while i < len(nodes):\n",
    "            node, v = nodes[i]\n",
    "            i += 1\n",
    "            if node:\n",
    "                nodes.append((node.left, 2*v))\n",
    "                nodes.append((node.right, 2*v+1))\n",
    "\n",
    "        return  nodes[-1][1] == len(nodes) # 标号正确，则倒数第二行满，则前n-2行均满\n",
    "\n",
    "# 作者：LeetCode\n",
    "# 链接：https://leetcode.cn/problems/check-completeness-of-a-binary-tree/solutions/18187/er-cha-shu-de-wan-quan-xing-jian-yan-by-leetcode/\n",
    "# 来源：力扣（LeetCode）\n",
    "# 著作权归作者所有。商业转载请联系作者获得授权，非商业转载请注明出处。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkDistances(self, s: str, distance: List[int]) -> bool:\n",
    "        n = len(s)\n",
    "        for i in range(n):\n",
    "            for j in range(i+1,n):\n",
    "                if s[i]==s[j] and distance[ord(s[i])-ord('a')]!=j-i-1:\n",
    "                    return False\n",
    "        return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkDistances(self, s: str, distance: List[int]) -> bool:\n",
    "        checklist = {}\n",
    "        temp = 0\n",
    "\n",
    "        for i in range(len(s)):\n",
    "            if s[i] not in checklist.keys():\n",
    "                checklist[s[i]] = i\n",
    "            else:\n",
    "                temp = i - checklist[s[i]] - 1\n",
    "                if temp != distance[ord(s[i]) - ord('a')]:\n",
    "                    return False\n",
    "        \n",
    "        return True\n",
    "\n",
    "        \n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkDistances(self, s: str, distance: List[int]) -> bool:\n",
    "        checklist = {}\n",
    "        temp = 0\n",
    "\n",
    "        for i in range(len(s)):\n",
    "            if s[i] not in checklist.keys():\n",
    "                checklist[s[i]] = i\n",
    "            else:\n",
    "                temp = i - checklist[s[i]] - 1\n",
    "                if temp != distance[ord(s[i]) - ord('a')]:\n",
    "                    return False\n",
    "        \n",
    "        return True\n",
    "\n",
    "        \n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkDistances(self, s: str, distance: List[int]) -> bool:\n",
    "        s_len = len(s)\n",
    "        for i in range(s_len): #遍历\n",
    "            for j in range(i + 1, s_len): #i 到j的距离\n",
    "                if s[i] == s[j]: #找到了相同字母的\n",
    "                    if distance[ord(s[i]) - ord('a')] != j - i - 1: #距离\n",
    "                        return False\n",
    "                    else:  #这里是剪枝\n",
    "                        break  \n",
    "        return True\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkDistances(self, s: str, distance: List[int]) -> bool:\n",
    "        counter=dict()\n",
    "        n=len(s)\n",
    "        for i in range(n):\n",
    "            counter[s[i]]=counter.get(s[i],[])+[i]\n",
    "        for key in counter:\n",
    "            if counter[key][1]-counter[key][0]-1!=distance[ord(key)-ord('a')]:\n",
    "                return False\n",
    "        return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkDistances(self, s: str, distance: List[int]) -> bool:\n",
    "        n = len(s)\n",
    "        for d, c in zip(distance, ascii_lowercase):\n",
    "            i = s.find(c)\n",
    "            if i == -1:\n",
    "                continue\n",
    "            if i+d+1 >= n:\n",
    "                return False\n",
    "            if s[i+d+1] != c:\n",
    "                return False\n",
    "        return True\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkDistances(self, s: str, distance: List[int]) -> bool:\n",
    "        n = len(s)\n",
    "        firstIndex = [0] * 26\n",
    "        for i in range(n):\n",
    "            idx = ord(s[i]) - ord('a')\n",
    "            if firstIndex[idx] and i - firstIndex[idx] != distance[idx]:\n",
    "                return False\n",
    "            firstIndex[idx] = i + 1\n",
    "        return True\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkDistances(self, s: str, distance: List[int]) -> bool:\n",
    "        alphabet = list(map(lambda x:chr(x),range(97,123)))\n",
    "        left = -1\n",
    "        for ch in alphabet:\n",
    "            left += 1\n",
    "            if ch in s:\n",
    "                if s.rfind(ch) - s.find(ch) -1 != distance[left]:\n",
    "                    return False\n",
    "        else:\n",
    "            return True\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkDistances(self, s: str, distance: List[int]) -> bool:\n",
    "        for i in range(len(s)):\n",
    "            for j in range(i+1, len(s)):\n",
    "                if s[i] == s[j]:\n",
    "                    if distance[ord(s[i])-ord('a')] != j-i-1:\n",
    "                        return False\n",
    "        return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkDistances(self, s: str, distance: List[int]) -> bool:\n",
    "        vals = {}\n",
    "        for i in range(len(s)):\n",
    "            if s[i] not in vals:\n",
    "                vals[s[i]] = [i]\n",
    "            else:\n",
    "                vals[s[i]].append(i)\n",
    "        ns = list(set(s))\n",
    "        for i in range(len(ns)):\n",
    "            if vals[ns[i]][1] - vals[ns[i]][0] - 1 != distance[ord(ns[i]) - ord('a')]:\n",
    "                return False\n",
    "        return True\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkDistances(self, s: str, distance: List[int]) -> bool:\n",
    "        dis={}\n",
    "        for i,v in enumerate(s):\n",
    "            if v in dis:\n",
    "                index=ord(v)-97\n",
    "                if distance[index]!=(i-dis[v]-1):\n",
    "                    return False\n",
    "            else:\n",
    "                dis[v]=i\n",
    "        return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkDistances(self, s: str, distance: List[int]) -> bool:\n",
    "        n = len(s)\n",
    "        for i in range(n):\n",
    "            for j in range(i + 1, n):\n",
    "                if s[i] == s[j] and distance[ord(s[i]) - ord('a')] != j - i - 1:\n",
    "                    return False\n",
    "        return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkDistances(self, s: str, distance: List[int]) -> bool:\n",
    "        m = {}\n",
    "        for i in range(len(s)):\n",
    "            index = ord(s[i]) - 97\n",
    "            if index not in m.keys():\n",
    "                m[index] = [i]\n",
    "            else:\n",
    "                m[index].append(i)\n",
    "        # print(m)\n",
    "        for i, d in enumerate(distance):\n",
    "            if i not in m.keys():\n",
    "                continue\n",
    "            pos = m[i]\n",
    "            if abs(pos[1]-pos[0]-1) != d:\n",
    "                return False\n",
    "        return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkDistances(self, s: str, distance: List[int]) -> bool:\n",
    "        n = len(s)\n",
    "        for d, c in zip(distance, ascii_lowercase):\n",
    "            i = s.find(c)\n",
    "            if i == -1:\n",
    "                continue\n",
    "            if i+d+1 >= n:\n",
    "                return False\n",
    "            if s[i+d+1] != c:\n",
    "                return False\n",
    "        return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkDistances(self, s: str, distance: List[int]) -> bool:\n",
    "        for i in range(len(s)-1):\n",
    "            for j in range(i+1,len(s)):\n",
    "                if s[j]==s[i]:\n",
    "                    if (j-i-1)!=distance[ord(s[i])-ord(\"a\")]:\n",
    "                        return False\n",
    "                    break\n",
    "        return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkDistances(self, s: str, distance: List[int]) -> bool:\n",
    "        dic = {}\n",
    "        for i, v in enumerate(s):\n",
    "            if v not in dic:\n",
    "                dic[v] = i\n",
    "        for j in dic.keys():\n",
    "            nextIndex = dic[j] + distance[ord(j) - ord('a')] + 1\n",
    "            if nextIndex >= len(s) or s[dic[j]] != s[nextIndex]:\n",
    "                return False\n",
    "        return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkDistances(self, s: str, distance: List[int]) -> bool:\n",
    "        res = []\n",
    "        n = len(s)\n",
    "        for i in range(n):\n",
    "            if s[i] not in res:\n",
    "                pos = ord(s[i]) - ord('a')\n",
    "                d = distance[pos]\n",
    "                if i+ d + 1 >= n or  s[i+ d + 1] != s[i] :\n",
    "                    return False\n",
    "                res.append(s[i])\n",
    "                if len(res) == n / 2:\n",
    "                    break\n",
    "        return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkDistances(self, s: str, distance: List[int]) -> bool:\n",
    "        n=len(s)\n",
    "        for i in range(n):\n",
    "            for j in range(i+1,n):\n",
    "                if s[i] == s[j] and distance[ord(s[i])-ord('a')] != j-i-1:\n",
    "                    return False\n",
    "        return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkDistances(self, s: str, distance: List[int]) -> bool:\n",
    "        n = len(s)\n",
    "        for i in range(n):\n",
    "            for j in range(i + 1, n):\n",
    "                if s[i] == s[j] and distance[ord(s[i]) - ord('a')] != j - i - 1:\n",
    "                    return False\n",
    "        return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkDistances(self, s: str, distance: List[int]) -> bool:\n",
    "        n = len(s)\n",
    "        flag = {}\n",
    "        for i in range(n):\n",
    "            if s[i] not in flag.keys():\n",
    "                flag[s[i]] = i\n",
    "            elif i-flag[s[i]] != distance[ord(s[i])-ord('a')]+1:\n",
    "                return False\n",
    "        return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkDistances(self, s: str, distance: List[int]) -> bool:\n",
    "        alphabet = list(map(lambda x:chr(x),range(97,123)))\n",
    "        left = -1\n",
    "        for ch in alphabet:\n",
    "            left += 1\n",
    "            if ch in s:\n",
    "                if s.rfind(ch) - s.find(ch) -1 != distance[left]:\n",
    "                    return False\n",
    "        else:\n",
    "            return True\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkDistances(self, s: str, distance: List[int]) -> bool:\n",
    "        a={}\n",
    "        for i,j in enumerate(s):\n",
    "            if j not in a:\n",
    "                a[j]=[i]\n",
    "            else:\n",
    "                a[j].append(i)\n",
    "        for i in a.keys():\n",
    "            if distance[ord(i)-97]!=a[i][1]-a[i][0]-1:\n",
    "                return False\n",
    "                break\n",
    "        else:\n",
    "            return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkDistances(self, s: str, distance: List[int]) -> bool:\n",
    "        s_len = len(s)\n",
    "        for i in range(s_len):\n",
    "            for j in range(i + 1, s_len):\n",
    "                if s[i] == s[j]:\n",
    "                    if distance[ord(s[i]) - ord('a')] != j - i - 1:\n",
    "                        return False\n",
    "                    else:\n",
    "                        break\n",
    "        return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkDistances(self, s: str, distance: List[int]) -> bool:\n",
    "        pre = {}\n",
    "        for i, c in enumerate(s):\n",
    "            if c not in pre:\n",
    "                pre[c] = i\n",
    "            else:\n",
    "                diff = i - pre[c] - 1\n",
    "                if diff != distance[ord(c)-ord('a')]: return False\n",
    "        return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkDistances(self, s: str, distance: List[int]) -> bool:\n",
    "        s_dic = {}\n",
    "        for idx,tmp_s in enumerate(list(s)):\n",
    "            if s_dic.get(tmp_s) != None:\n",
    "                s_dic[ tmp_s ] = (idx - 1 - s_dic[ tmp_s ])\n",
    "            else:\n",
    "                s_dic[ tmp_s ] = idx\n",
    "        for i in s_dic.keys():\n",
    "            if s_dic[i] == distance[ord(i)- ord('a')]:\n",
    "                continue\n",
    "            else:\n",
    "                return False\n",
    "        return True "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkDistances(self, s: str, distance: List[int]) -> bool:\n",
    "        dic = {}\n",
    "        for i, ch in enumerate(s):\n",
    "            if ch not in dic:\n",
    "                dic[ch] = i\n",
    "            elif i - dic[ch] - 1 != distance[ord(ch) - ord('a')]:\n",
    "                    return False\n",
    "\n",
    "        return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkDistances(self, s: str, distance: List[int]) -> bool:\n",
    "        s_len = len(s)\n",
    "        for i in range(s_len):\n",
    "            for j in range(i + 1, s_len):\n",
    "                if s[i] == s[j]:\n",
    "                    if distance[ord(s[i]) - ord('a')] != j - i - 1:\n",
    "                        return False\n",
    "                    else:\n",
    "                        break\n",
    "        return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkDistances(self, s: str, distance: List[int]) -> bool:\n",
    "        n=len(s)\n",
    "        for i in range(n):\n",
    "            for j in range(i+1,n):\n",
    "                if s[i]==s[j] and distance[ord(s[i])-ord('a')]!=j-i-1:\n",
    "                    return False\n",
    "        return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkDistances(self, s: str, distance: List[int]) -> bool:\n",
    "        n = len(s)\n",
    "        chars = set()\n",
    "        for i in range(n):\n",
    "            if s[i] not in chars:\n",
    "                j = i + 1 + distance[ord(s[i]) - ord('a')]\n",
    "                if j >= n or s[i] != s[j]:\n",
    "                    return False\n",
    "                chars.add(s[i])\n",
    "        return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkDistances(self, s: str, distance: List[int]) -> bool:\n",
    "        s_len=len(s)\n",
    "        for i in range(s_len):\n",
    "            d = distance[ord(s[i])-ord('a')]\n",
    "            if d!=-1 and (d+i+1>=s_len or s[d+i+1]!=s[i]):\n",
    "                return False\n",
    "            distance[ord(s[i])-ord('a')] = -1\n",
    "        return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkDistances(self, s: str, distance: List[int]) -> bool:\n",
    "        if len(s) >100:\n",
    "            return True\n",
    "\n",
    "        dis = [-1]*26\n",
    "\n",
    "        for i, ch in enumerate(s):\n",
    "            index = ord(ch) - ord(\"a\")\n",
    "            dis [index] = i if dis[index]==-1 else i-dis[index]-1\n",
    "        for i, n in enumerate(distance):\n",
    "            if dis[i] == -1:\n",
    "                continue\n",
    "            if dis[i] != n:\n",
    "                return False\n",
    "        return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkDistances(self, s: str, distance: List[int]) -> bool:\n",
    "        dct = defaultdict(list)\n",
    "        for i, w in enumerate(s):\n",
    "            dct[w].append(i)\n",
    "        for w in dct:\n",
    "            i = ord(w) - ord(\"a\")\n",
    "            if dct[w][-1]-dct[w][0]-1 != distance[i]:\n",
    "                return False\n",
    "        return True\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkDistances(self, s: str, distance: List[int]) -> bool:\n",
    "        for i in range(26):\n",
    "            c = chr(ord('a') + i)\n",
    "            l = []\n",
    "            for j, ch in enumerate(s):\n",
    "                if ch == c:\n",
    "                    l.append(j)\n",
    "            if not l:\n",
    "                continue\n",
    "            if l[1] - l[0] - 1 != distance[i]:\n",
    "                return False\n",
    "        return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkDistances(self, s: str, distance: List[int]) -> bool:\n",
    "        flag = []\n",
    "        for i in range(len(s)):\n",
    "            if s[i] not in flag:\n",
    "                if i + 1 + distance[ord(s[i]) - 97] >= len(s):\n",
    "                    return False\n",
    "                if s[i] != s[i + distance[ord(s[i]) - 97] + 1]:\n",
    "                    return False\n",
    "                flag.append(s[i])\n",
    "        return True\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkDistances(self, s: str, distance: List[int]) -> bool:\n",
    "        dis=[0]*26\n",
    "        for i in range(len(s)):\n",
    "            for j in range(i+1,len(s)):\n",
    "                if s[i]==s[j] and distance[ord(s[i])-ord('a')]!=j-i-1:\n",
    "                    return False\n",
    "        return True\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkDistances(self, s: str, distance: List[int]) -> bool:\n",
    "        chars = {}\n",
    "        for i in range(len(s)):\n",
    "            if s[i] not in chars.keys():\n",
    "                chars[s[i]] = i\n",
    "            else:\n",
    "                chars[s[i]] = i - chars[s[i]] -1\n",
    "        for index in range(26):\n",
    "            if chr(ord('a')+index) in chars.keys():\n",
    "                if distance[index] == chars[chr(ord('a')+index)]:\n",
    "                    continue\n",
    "                else:\n",
    "                    return False\n",
    "        return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkDistances(self, s: str, distance: List[int]) -> bool:\n",
    "        for i in range(len(s)):\n",
    "            if distance[ord(s[i]) - 97] != -1:\n",
    "                if i + 1 + distance[ord(s[i]) - 97] >= len(s):\n",
    "                    return False\n",
    "                if s[i] != s[i + distance[ord(s[i]) - 97] + 1]:\n",
    "                    return False\n",
    "                distance[ord(s[i]) - 97] = -1\n",
    "        return True\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkDistances(self, s: str, distance: List[int]) -> bool:\n",
    "        dic = {}\n",
    "        for i in range(len(s)):\n",
    "            dic[s[i]] = dic.get(s[i], []) + [i]\n",
    "        return all(distance[ord(k) - 97] == v[1] - v[0] - 1 for k, v in dic.items())\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkDistances(self, s: str, distance: List[int]) -> bool:\n",
    "        dis = [-1]*26\n",
    "\n",
    "        for i, ch in enumerate(s):\n",
    "            index = ord(ch) - ord(\"a\")\n",
    "            dis [index] = i if dis[index]==-1 else i-dis[index]-1\n",
    "        for i, n in enumerate(distance):\n",
    "            if dis[i] == -1:\n",
    "                continue\n",
    "            if dis[i] != n:\n",
    "                return False\n",
    "        return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkDistances(self, s: str, distance: List[int]) -> bool:\n",
    "        s_len = len(s)\n",
    "        for i in range(s_len): #遍历\n",
    "            for j in range(i + 1, s_len): #i 到j的距离\n",
    "                if s[i] == s[j]: #找到了相同字母的\n",
    "                    if distance[ord(s[i]) - ord('a')] != j - i - 1: #距离\n",
    "                        return False\n",
    "                    else:  #这里是剪枝\n",
    "                        break  \n",
    "        return True\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkDistances(self, s: str, distance: List[int]) -> bool:\n",
    "        length = len(s)\n",
    "        std = ord('a')\n",
    "        visited = set()\n",
    "        for i, c in enumerate(s):\n",
    "            if c in visited:\n",
    "                continue\n",
    "            new_p = i + distance[ord(c) - std] + 1\n",
    "            if new_p < length and s[new_p] == c:\n",
    "                visited.add(c)\n",
    "            else:\n",
    "                return False\n",
    "        return True\n",
    "            \n",
    "                "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkDistances(self, s: str, distance: List[int]) -> bool:\n",
    "        letters = string.ascii_lowercase\n",
    "        letters_dist = {}\n",
    "        for i in range(len(distance)):\n",
    "            letters_dist[letters[i]] = distance[i]\n",
    "        \n",
    "        visited = {}\n",
    "        \n",
    "       \n",
    "        for i in range(len(s)):\n",
    "            j = i + 1\n",
    "            if i in visited:\n",
    "                continue\n",
    "            while j<len(s) and s[j] != s[i]:\n",
    "                j += 1\n",
    "\n",
    "            visited[j] = None\n",
    "            \n",
    "            this_distance = j - i - 1\n",
    "            if this_distance != letters_dist[s[i]]:\n",
    "                return False\n",
    "        return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkDistances(self, s: str, distance: List[int]) -> bool:\n",
    "        s_len = len(s)\n",
    "        for i in range(s_len):\n",
    "            for j in range(i + 1, s_len):\n",
    "                if s[i] == s[j]:\n",
    "                    if distance[ord(s[i]) - ord('a')] != j - i - 1:\n",
    "                        return False\n",
    "                    else:\n",
    "                        break\n",
    "        return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkDistances(self, s: str, distance: List[int]) -> bool:\n",
    "        n = len(s)\n",
    "        for d, c in zip(distance, ascii_lowercase):\n",
    "            i = s.find(c)\n",
    "            if i == -1:\n",
    "                continue\n",
    "            if i+d+1 >= n:\n",
    "                return False\n",
    "            if s[i+d+1] != c:\n",
    "                return False\n",
    "        return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkDistances(self, s: str, distance: List[int]) -> bool:\n",
    "        letters = 'abcdefghijklmnopqrstuvwxyz'\n",
    "        d = {'a': 0, 'b': 1, 'c': 2, 'd': 3, 'e': 4, 'f': 5, 'g': 6, 'h': 7, 'i': 8, 'j': 9, 'k': 10, 'l': 11, 'm': 12, 'n': 13, 'o': 14, 'p': 15, 'q': 16, 'r': 17, 's': 18, 't': 19, 'u': 20, 'v': 21, 'w': 22, 'x': 23, 'y': 24, 'z': 25}\n",
    "        for letter in set(s):\n",
    "            l1 = s.find(letter)\n",
    "            l2 = s.rfind(letter)\n",
    "            if l2 - l1 - 1 != distance[d[letter]]:\n",
    "                return False\n",
    "        return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkDistances(self, s: str, distance: List[int]) -> bool:\n",
    "        n = len(s)\n",
    "        for i in range(n):\n",
    "            for j in range(i + 1, n):\n",
    "                if s[i] == s[j] and distance[ord(s[i]) - ord('a')] != j - i - 1:\n",
    "                    return False\n",
    "        return True\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkDistances(self, s: str, distance: List[int]) -> bool:\n",
    "        s_len = len(s)\n",
    "        for i in range(s_len):\n",
    "            for j in range(i + 1, s_len):\n",
    "                if s[i] == s[j] and distance[ord(s[i]) - ord('a')] != j - i - 1:\n",
    "                    return False\n",
    "        return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkDistances(self, s: str, distance: List[int]) -> bool:\n",
    "        distance_dict = collections.defaultdict(list)\n",
    "        for i in range(len(s)):\n",
    "            distance_dict[s[i]].append(i)\n",
    "        \n",
    "        for key, value in distance_dict.items():\n",
    "            if distance[ord(key) - ord('a')] != value[1] - value[0] - 1:\n",
    "                return False\n",
    "        return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkDistances(self, s: str, distance: List[int]) -> bool:\n",
    "        length = len(s)\n",
    "        std = ord('a')\n",
    "        flag = [0] * length\n",
    "        for i, c in enumerate(s):\n",
    "            if flag[i] == 1:\n",
    "                continue\n",
    "            new_p = i + distance[ord(c) - std] + 1\n",
    "            if new_p < length and s[new_p] == c:\n",
    "                flag[new_p] = 1\n",
    "            else:\n",
    "                return False\n",
    "        return True\n",
    "            \n",
    "                "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkDistances(self, s: str, distance: List[int]) -> bool:\n",
    "      checked = {}\n",
    "      for i,x in enumerate(s):\n",
    "        if x in checked:\n",
    "          continue\n",
    "        dist = distance['abcdefghijklmnopqrstuvwxyz'.index(x)]\n",
    "        j = i+dist+1\n",
    "        try:\n",
    "          if s[j] ==x:\n",
    "            checked[x] = True\n",
    "          else:\n",
    "            return False\n",
    "        except:\n",
    "          return False\n",
    "      return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkDistances(self, s: str, distance: List[int]) -> bool:\n",
    "        res = []\n",
    "        n = len(s)\n",
    "        for i in range(n):\n",
    "            if s[i] not in res:\n",
    "                pos = ord(s[i]) - ord('a')\n",
    "                d = distance[pos]\n",
    "                if i+ d + 1 >= n or  s[i+ d + 1] != s[i] :\n",
    "                    return False\n",
    "                res.append(s[i])\n",
    "        return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkDistances(self, s: str, distance: List[int]) -> bool:\n",
    "        base = ord('a')\n",
    "        adic = {}\n",
    "        for i in range(len(s)):\n",
    "            if s[i] in adic:\n",
    "                adic[s[i]].append(i)\n",
    "            else:\n",
    "                adic[s[i]] = [i]\n",
    "        for k,v in adic.items():\n",
    "            i = ord(k)-base\n",
    "            if distance[i] != (v[1]-v[0]-1):\n",
    "                return False\n",
    "\n",
    "        return True\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkDistances(self, s: str, distance: List[int]) -> bool:\n",
    "        d = defaultdict(int)\n",
    "        for i, c in enumerate(s, 1):\n",
    "            if d[c] and i - d[c] - 1 != distance[ord(c) - ord('a')]:\n",
    "                return False\n",
    "            d[c] = i\n",
    "        return True\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkDistances(self, s: str, distance: List[int]) -> bool:\n",
    "        n = len(s)\n",
    "        pos = [-1] * 26\n",
    "        for i, ch in enumerate(s):\n",
    "            if pos[ord(ch) - ord('a')] == -1:\n",
    "                pos[ord(ch) - ord('a')] = i\n",
    "            elif i - pos[ord(ch) - ord('a')] - 1 != distance[ord(ch) - ord('a')]:\n",
    "                return False\n",
    "        return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkDistances(self, s: str, distance: List[int]) -> bool:\n",
    "        for w in set(s):\n",
    "            ind = ord(w) - ord('a')\n",
    "            if s.rfind(w) - s.find(w) -1 != distance[ind]:\n",
    "                return False\n",
    "        return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkDistances(self, s: str, distance: List[int]) -> bool:\n",
    "        for i in range(len(s)):\n",
    "            j = ord(s[i]) - ord('a');\n",
    "            if distance[j] >= 0:\n",
    "                distance[j] = -(i + distance[j] + 1)\n",
    "            else:\n",
    "                if i!= -distance[j]:\n",
    "                    return False\n",
    "        return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkDistances(self, s: str, distance: List[int]) -> bool:\n",
    "        s_len = len(s)\n",
    "        for i in range(s_len):\n",
    "            for j in range(i + 1, s_len):\n",
    "                if s[i] == s[j] and distance[ord(s[i]) - ord('a')] != j - i - 1:\n",
    "                    return False\n",
    "        return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkDistances(self, s: str, distance: List[int]) -> bool:\n",
    "        dic = {}\n",
    "        for i in range(len(s)):\n",
    "            dic[s[i]] = dic.get(s[i], []) + [i]\n",
    "        print(dic)\n",
    "        for k, v in dic.items():\n",
    "            if distance[ord(k) - 97] != v[1] - v[0] - 1:\n",
    "                return False\n",
    "        return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkDistances(self, s: str, distance: List[int]) -> bool:\n",
    "        s_len = len(s)\n",
    "        for i in range(s_len):\n",
    "            for j in range(i + 1, s_len):\n",
    "                if s[i] == s[j] and distance[ord(s[i]) - ord('a')] != j - i - 1:\n",
    "                    return False\n",
    "        return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkDistances(self, s: str, distance: List[int]) -> bool:\n",
    "        d = {}\n",
    "        for index, ss in enumerate(s):\n",
    "            if ss in d:\n",
    "                d[ss].append(index)\n",
    "            else:\n",
    "                d[ss] = [index]\n",
    "        for key, val in d.items():\n",
    "            if distance[ord(key) - ord('a')] != val[1] - val[0] - 1:\n",
    "                return False\n",
    "        return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkDistances(self, s: str, distance: List[int]) -> bool:\n",
    "        s_dict = {\n",
    "        'a': 0,'b': 1,'c': 2, 'd': 3,'e': 4,'f': 5,'g': 6,\n",
    "        'h': 7,'i': 8,'j': 9, 'k': 10,'l': 11,'m': 12,'n': 13,\n",
    "        'o': 14,'p': 15,'q': 16, 'r': 17,'s': 18,'t':19,'u':20,\n",
    "        'v': 21,'w': 22,'x': 23, 'y': 24,'z': 25\n",
    "        }\n",
    "        distance1=[-1]*26\n",
    "        for i in range (len(s)):\n",
    "            if distance1[s_dict[s[i]]] ==-1:\n",
    "                distance1[s_dict[s[i]]]=i\n",
    "            else:\n",
    "                distance1[s_dict[s[i]]]=i-distance1[s_dict[s[i]]]-1\n",
    "\n",
    "        for i in range(26):\n",
    "            if distance1[i]!=-1:\n",
    "                if distance1[i]!=distance[i]:\n",
    "                    return False\n",
    "        return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkDistances(self, s: str, distance: List[int]) -> bool:\n",
    "        Set = set(s)\n",
    "        print(Set)\n",
    "        for i in Set:\n",
    "            if distance[ord(i) - 97] != len(s.split(i)[1]):\n",
    "                return False\n",
    "        return True\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkDistances(self, s: str, distance: List[int]) -> bool:\n",
    "        hax = {}\n",
    "        for i, x in enumerate(s):\n",
    "            num = ord(x) - 97\n",
    "            if num not in hax:\n",
    "                hax[num] = i\n",
    "            else:\n",
    "                hax[num] = i - hax[num]-1\n",
    "                if hax[num] != distance[num]:\n",
    "                    return False\n",
    "\n",
    "        return True\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkDistances(self, s: str, distance: List[int]) -> bool:\n",
    "        d = dict()\n",
    "        for i in range(len(s)):\n",
    "            if s[i] not in d:\n",
    "                d[s[i]] = i\n",
    "            else:\n",
    "                tem = i-d[s[i]]-1\n",
    "                if distance[ord(s[i])-97] != tem:\n",
    "                    return False\n",
    "        return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkDistances(self, s: str, distance: List[int]) -> bool:\n",
    "        dis = [-1]*26\n",
    "\n",
    "        for i, ch in enumerate(s):\n",
    "            index = ord(ch) - ord(\"a\")\n",
    "            dis [index] = i if dis[index]==-1 else i-dis[index]-1\n",
    "        for i, n in enumerate(distance):\n",
    "            if dis[i] == -1:\n",
    "                continue\n",
    "            if dis[i] != n:\n",
    "                return False\n",
    "        return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkDistances(self, s: str, distance: List[int]) -> bool:\n",
    "        d1={}\n",
    "        for i in range(len(s)):\n",
    "            if s[i] not in d1:\n",
    "                d1[s[i]]=[i]\n",
    "            else:\n",
    "                d1[s[i]].append(i)\n",
    "        for i in range(26):\n",
    "            if chr(i+97) in d1 and distance[i] != d1[chr(i+97)][1]-d1[chr(i+97)][0]-1:\n",
    "                return False\n",
    "        return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkDistances(self, s: str, distance: List[int]) -> bool:\n",
    "        s_len = len(s)\n",
    "        for i in range(s_len):\n",
    "            for j in range(i + 1, s_len):\n",
    "                if s[i] == s[j]:\n",
    "                    if distance[ord(s[i]) - ord('a')] != j - i - 1:\n",
    "                        return False\n",
    "                    else:\n",
    "                        break\n",
    "        return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkDistances(self, s: str, distance: List[int]) -> bool:\n",
    "        str_dict = {}\n",
    "        for i in range(len(s)):\n",
    "            if s[i] in str_dict.keys():\n",
    "                dis = i - str_dict[s[i]] - 1\n",
    "                index = ord(s[i]) - ord('a')\n",
    "                if dis != distance[index]:\n",
    "                    return False\n",
    "            else:\n",
    "                str_dict[s[i]] = i\n",
    "        return True\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkDistances(self, s: str, distance: List[int]) -> bool:\n",
    "        ans = []\n",
    "        for a,i in enumerate(s) :\n",
    "            if i not in ans:\n",
    "                #print(ord(i))\n",
    "                #print(s[int(distance[ord(i) - 97]) + a])\n",
    "                if distance[ord(i) - 97] + a +1> len(s) - 1:\n",
    "                    return False\n",
    "                if s[distance[ord(i) - 97] + a +1] != i:\n",
    "                    return False\n",
    "                else:\n",
    "                    ans.append(i)\n",
    "        return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkDistances(self, s: str, distance: List[int]) -> bool:\n",
    "        s_len = len(s)\n",
    "        for i in range(s_len):\n",
    "            for j in range(i + 1, s_len):\n",
    "                if s[i] == s[j]:\n",
    "                    if distance[ord(s[i]) - ord('a')] != j - i - 1:\n",
    "                        return False\n",
    "                    else:\n",
    "                        break\n",
    "        return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkDistances(self, s: str, distance: List[int]) -> bool:\n",
    "        last = [0] * 26\n",
    "        for i, c in enumerate(s):\n",
    "            c = ord(c) - ord('a')\n",
    "            if last[c] and i - last[c] != distance[c]:\n",
    "                return False\n",
    "            last[c] = i + 1\n",
    "        return True\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkDistances(self, s: str, distance: List[int]) -> bool:\n",
    "        n = len(s)\n",
    "        firstIndex = [0] * 26;\n",
    "        for i in range(n):\n",
    "            idx = ord(s[i]) - ord('a');\n",
    "            if firstIndex[idx] and i - firstIndex[idx] != distance[idx]:\n",
    "                return False\n",
    "            firstIndex[idx] = i + 1\n",
    "        return True\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "from typing import List\n",
    "\n",
    "class Solution:\n",
    "    def checkDistances(self, s: str, distance: List[int]) -> bool:\n",
    "        # 初始化一个字典来存储每个字母的首次和最后一次出现的索引\n",
    "        letter_indices = {}\n",
    "        \n",
    "        # 遍历字符串，记录每个字母的首次和最后一次出现的索引\n",
    "        for i, letter in enumerate(s):\n",
    "            if letter not in letter_indices:\n",
    "                letter_indices[letter] = [i, i]\n",
    "            else:\n",
    "                letter_indices[letter][1] = i\n",
    "        \n",
    "        # 检查每个字母的实际距离是否符合 distance 中的距离\n",
    "        for letter, indices in letter_indices.items():\n",
    "            # 计算实际的内部距离\n",
    "            actual_distance = indices[1] - indices[0] - 1\n",
    "            # 获取字母对应的 distance 数组中的索引（'a' -> 0, 'b' -> 1, ... 'z' -> 25）\n",
    "            letter_index = ord(letter) - ord('a')\n",
    "            # 如果实际距离与 distance 数组中的距离不符，返回 False\n",
    "            if distance[letter_index] != actual_distance:\n",
    "                return False\n",
    "\n",
    "        # 如果所有字母的距离都符合 distance 数组中的定义，返回 True\n",
    "        return True\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# from collections import defaultdict\n",
    "# class Solution:\n",
    "#     def checkDistances(self, s: str, distance: List[int]) -> bool:\n",
    "#         dic=defaultdict(list)\n",
    "#         for i,ch in enumerate(s):\n",
    "#             dic[ch].append(i)   \n",
    "#         for k,v in dic.items():\n",
    "#             if len(v)!=2:\n",
    "#                 return False   \n",
    "#             idx=ord(k)-ord(\"a\")\n",
    "#             value=v[1]-1-v[0]\n",
    "#             if distance[idx]!=value:\n",
    "#                 return False \n",
    "#         return True\n",
    "\n",
    "### 官2：模拟（推荐）\n",
    "class Solution:\n",
    "    def checkDistances(self, s: str, distance: List[int]) -> bool:\n",
    "        n = len(s)\n",
    "        firstIndex = [0] * 26; ### 记录字母曾经出现过的第一次位置索引\n",
    "        for i in range(n):\n",
    "            idx = ord(s[i]) - ord('a');\n",
    "            if firstIndex[idx] and i - firstIndex[idx] != distance[idx]:\n",
    "                return False\n",
    "            firstIndex[idx] = i + 1\n",
    "        return True\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "from typing import List\n",
    "\n",
    "class Solution:\n",
    "    def checkDistances(self, s: str, distance: List[int]) -> bool:\n",
    "        # 初始化一个字典来存储每个字母的首次和最后一次出现的索引\n",
    "        letter_indices = {}\n",
    "        \n",
    "        # 遍历字符串，记录每个字母的首次和最后一次出现的索引\n",
    "        for i, letter in enumerate(s):\n",
    "            if letter not in letter_indices:\n",
    "                letter_indices[letter] = [i, i]\n",
    "            else:\n",
    "                letter_indices[letter][1] = i\n",
    "        \n",
    "        # 检查每个字母的实际距离是否符合 distance 中的距离\n",
    "        for letter, indices in letter_indices.items():\n",
    "            # 计算实际的内部距离\n",
    "            actual_distance = indices[1] - indices[0] - 1\n",
    "            # 获取字母对应的 distance 数组中的索引（'a' -> 0, 'b' -> 1, ... 'z' -> 25）\n",
    "            letter_index = ord(letter) - ord('a')\n",
    "            # 如果实际距离与 distance 数组中的距离不符，返回 False\n",
    "            if distance[letter_index] != actual_distance:\n",
    "                return False\n",
    "\n",
    "        # 如果所有字母的距离都符合 distance 数组中的定义，返回 True\n",
    "        return True\n",
    "\n",
    "# 示例使用\n",
    "solution = Solution()\n",
    "s = \"abac\"\n",
    "distance = [1] * 26\n",
    "print(solution.checkDistances(s, distance))  # 应返回 True 或 False\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkDistances(self, s: str, distance: List[int]) -> bool:\n",
    "        ma={}\n",
    "        for i in range(len(s)):\n",
    "            if s[i] not in ma:\n",
    "                ma[s[i]] =i\n",
    "            else:\n",
    "                dis=i-ma[s[i]]-1\n",
    "                if distance[ord(s[i])-ord(\"a\")]!=dis:\n",
    "                    return False\n",
    "        return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "from typing import List\n",
    "\n",
    "class Solution:\n",
    "    def checkDistances(self, s: str, distance: List[int]) -> bool:\n",
    "        # 初始化一个字典来存储每个字母的首次和最后一次出现的索引\n",
    "        letter_indices = {}\n",
    "        \n",
    "        # 遍历字符串，记录每个字母的首次和最后一次出现的索引\n",
    "        for i, letter in enumerate(s):\n",
    "            if letter not in letter_indices:\n",
    "                letter_indices[letter] = [i, i]\n",
    "            else:\n",
    "                letter_indices[letter][1] = i\n",
    "        \n",
    "        # 检查每个字母的实际距离是否符合 distance 中的距离\n",
    "        for letter, indices in letter_indices.items():\n",
    "            # 计算实际的内部距离\n",
    "            actual_distance = indices[1] - indices[0] - 1\n",
    "            # 获取字母对应的 distance 数组中的索引（'a' -> 0, 'b' -> 1, ... 'z' -> 25）\n",
    "            letter_index = ord(letter) - ord('a')\n",
    "            # 如果实际距离与 distance 数组中的距离不符，返回 False\n",
    "            if distance[letter_index] != actual_distance:\n",
    "                return False\n",
    "\n",
    "        # 如果所有字母的距离都符合 distance 数组中的定义，返回 True\n",
    "        return True\n",
    "\n",
    "# 示例使用\n",
    "solution = Solution()\n",
    "s = \"abac\"\n",
    "distance = [1] * 26\n",
    "print(solution.checkDistances(s, distance))  # 应返回 True 或 False\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def canBeValid(self, s: str, locked: str) -> bool:\n",
    "        m, n = len(s), len(locked)\n",
    "        if m != n or m & 1: return False\n",
    "\n",
    "        def check(s: str, locked: str, parenthesis: int) -> bool:\n",
    "            count = 0\n",
    "            l = len(s)\n",
    "            for i in range(l):\n",
    "                if locked[i] == '1':\n",
    "                    if s[i] == parenthesis:\n",
    "                        count += 1\n",
    "                    else :\n",
    "                        count -= 1\n",
    "                        if count < 0:   return False\n",
    "                # for unlocked case, increment count to avoid it go below 0\n",
    "                elif locked[i] == '0':\n",
    "                    count += 1\n",
    "            return True\n",
    "        \n",
    "        return check(s, locked, '(') and check(s[::-1], locked[::-1], ')')\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkIfCanBreak(self, s1: str, s2: str) -> bool:\n",
    "        # l1,l2=list(str(s1)),list(str(s2))\n",
    "        n=len(s1)\n",
    "        \n",
    "        l=[0]*26\n",
    "        for i in s2:\n",
    "            l[ord(i)-ord('a')]+=1\n",
    "            \n",
    "        for i in range(n):\n",
    "            ch=s1[i]\n",
    "            index=ord(ch)-ord('a')\n",
    "            flag=0\n",
    "            for j in range(index,26):\n",
    "                if l[j]:\n",
    "                    l[j]-=1\n",
    "                    flag=1\n",
    "                    break\n",
    "        \n",
    "            if not flag:break\n",
    "        if flag:return True\n",
    "        \n",
    "        s2,s1=s1,s2\n",
    "        \n",
    "        l=[0]*26\n",
    "        for i in s2:\n",
    "            l[ord(i)-ord('a')]+=1\n",
    "            \n",
    "        for i in range(n):\n",
    "            ch=s1[i]\n",
    "            index=ord(ch)-ord('a')\n",
    "            flag=0\n",
    "            for j in range(index,26):\n",
    "                if l[j]:\n",
    "                    l[j]-=1\n",
    "                    flag=1\n",
    "                    break\n",
    "        \n",
    "            if not flag:break\n",
    "        if flag:return True\n",
    "        \n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkIfCanBreak(self, s1: str, s2: str) -> bool:\n",
    "        def f(s1, cnts):\n",
    "            for c in s1:\n",
    "                i = ord(c)-ord('a')\n",
    "                while i<26:\n",
    "                    if cnts[i]>0:\n",
    "                        cnts[i]-=1\n",
    "                        break\n",
    "                    i+=1\n",
    "                if i==26: return False\n",
    "            return True\n",
    "        def g(s):\n",
    "            res = [0]*26\n",
    "            for c in s:\n",
    "                res[ord(c)-ord('a')] += 1\n",
    "            return res\n",
    "        return f(s1, g(s2)) or f(s2, g(s1))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkIfCanBreak(self, s1: str, s2: str) -> bool:\n",
    "        length = len(s1)\n",
    "        s1_list = [0] * 26\n",
    "        s2_list = [0] * 26\n",
    "        for index in range(length):\n",
    "            s1_list[ord(s1[index]) - ord('a')] += 1\n",
    "            s2_list[ord(s2[index]) - ord('a')] += 1\n",
    "        return isBreak(s1_list.copy(), s2_list.copy()) or isBreak(s2_list, s1_list)\n",
    "        \n",
    "\n",
    "def isBreak(s1_list, s2_list):\n",
    "    s1_pointer = 0\n",
    "    s2_pointer = 0\n",
    "    while 1:\n",
    "        while s1_pointer < 26 and s1_list[s1_pointer] == 0:\n",
    "            s1_pointer += 1\n",
    "        if s1_pointer == 26:\n",
    "            return True\n",
    "        while s2_pointer < 26 and s2_list[s2_pointer] == 0:\n",
    "            s2_pointer += 1\n",
    "        if s2_pointer == 26:\n",
    "            return False \n",
    "        if s1_pointer > s2_pointer:\n",
    "            return False \n",
    "        elif s1_list[s1_pointer] <= s2_list[s2_pointer]:\n",
    "            s2_list[s2_pointer] -= s1_list[s1_pointer]\n",
    "            s1_pointer += 1\n",
    "        else: \n",
    "            s1_list[s1_pointer] -= s2_list[s2_pointer]\n",
    "            s2_pointer += 1\n",
    "                \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkIfCanBreak(self, s1: str, s2: str) -> bool:\n",
    "        st = [0 for _ in range(26)]\n",
    "        for i in range(len(s1)):\n",
    "            st[ord(s1[i]) - ord(\"a\")] -= 1\n",
    "            st[ord(s2[i]) - ord(\"a\")] += 1\n",
    "        ans, flag_one, flag_two = 0, True, True\n",
    "        for i in range(25, -1, -1):\n",
    "            ans += st[i]\n",
    "            if ans < 0:\n",
    "                flag_one = False\n",
    "            elif ans > 0:\n",
    "                flag_two = False\n",
    "\n",
    "        return flag_one or flag_two"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkIfCanBreak(self, s1: str, s2: str) -> bool:\n",
    "        length = len(s1)\n",
    "        s1_list = [0] * 26\n",
    "        s2_list = [0] * 26\n",
    "        for index in range(length):\n",
    "            s1_list[ord(s1[index]) - ord('a')] += 1\n",
    "            s2_list[ord(s2[index]) - ord('a')] += 1\n",
    "        return isBreak(s1_list.copy(), s2_list.copy()) or isBreak(s2_list, s1_list)\n",
    "        \n",
    "\n",
    "def isBreak(s1_list, s2_list):\n",
    "    s1_pointer = 0\n",
    "    s2_pointer = 0\n",
    "    while 1:\n",
    "        while s1_pointer < 26 and s1_list[s1_pointer] == 0:\n",
    "            s1_pointer += 1\n",
    "        if s1_pointer == 26:\n",
    "            return True\n",
    "        while s2_pointer < 26 and s2_list[s2_pointer] == 0:\n",
    "            s2_pointer += 1\n",
    "        if s2_pointer == 26:\n",
    "            return False \n",
    "        if s1_pointer > s2_pointer:\n",
    "            return False \n",
    "        elif s1_list[s1_pointer] <= s2_list[s2_pointer]:\n",
    "            s2_list[s2_pointer] -= s1_list[s1_pointer]\n",
    "            s1_pointer += 1\n",
    "        else: \n",
    "            s1_list[s1_pointer] -= s2_list[s2_pointer]\n",
    "            s2_pointer += 1\n",
    "                \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkIfCanBreak(self, s1: str, s2: str) -> bool:\n",
    "        a1 = [0 for _ in range(26)]\n",
    "        a2 = [0 for _ in range(26)]\n",
    "        for c in s1:\n",
    "            a1[ord(c) - ord('a')] += 1\n",
    "        for c in s2:\n",
    "            a2[ord(c) - ord('a')] += 1\n",
    "\n",
    "        flag1 = True\n",
    "        flag2 = True\n",
    "        acc1, acc2 = 0, 0\n",
    "\n",
    "        for x in range(26):\n",
    "            acc1 += a1[x]\n",
    "            acc2 += a2[x]\n",
    "            if acc1 < acc2:\n",
    "                flag1 = False\n",
    "            if acc2 < acc1:\n",
    "                flag2 = False\n",
    "        return flag1 or flag2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkIfCanBreak(self, s1: str, s2: str) -> bool:\n",
    "        c1 = Counter(s1)\n",
    "        c2 = Counter(s2)\n",
    "        diff = 0\n",
    "        s = set()\n",
    "        #和排序差不多。也是搭累计\n",
    "        for i in range(26):\n",
    "            c = chr(ord('a') + i)\n",
    "            diff += c1[c] - c2[c]\n",
    "            if diff:\n",
    "                s.add(diff > 0)\n",
    "        return len(s) < 2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkIfCanBreak(self, s1: str, s2: str) -> bool:\n",
    "        c1 = Counter(s1)\n",
    "        c2 = Counter(s2)\n",
    "        diff = 0\n",
    "        s = set()\n",
    "        for i in range(26):\n",
    "            c = chr(ord('a') + i)\n",
    "            diff += c1[c] - c2[c]\n",
    "            if diff:\n",
    "                s.add(diff > 0)\n",
    "        return len(s) < 2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkIfCanBreak(self, s1: str, s2: str) -> bool:\n",
    "        count1 = [0] * 26\n",
    "        count2 = [0] * 26\n",
    "        a = ord('a')\n",
    "        for i in range(len(s1)):\n",
    "            count1[ord(s1[i]) - a] += 1\n",
    "            count2[ord(s2[i]) - a] += 1\n",
    "        idx1 = 0\n",
    "        idx2 = 0\n",
    "        mask1 = -1\n",
    "        mask2 = -1\n",
    "        for i in range(len(s1)):\n",
    "            while count1[idx1] == 0:\n",
    "                idx1 += 1\n",
    "            while count2[idx2] == 0:\n",
    "                idx2 += 1\n",
    "            if idx1 > idx2:\n",
    "                mask1 = 1\n",
    "            if idx1 < idx2:\n",
    "                mask2 = 1\n",
    "            count1[idx1] -= 1\n",
    "            count2[idx2] -= 1\n",
    "            if mask1 == mask2 == 1:\n",
    "                return False\n",
    "        return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkIfCanBreak(self, s1: str, s2: str) -> bool:\n",
    "        cnt = [0] * 26\n",
    "        for i in range(len(s1)):\n",
    "            cnt[ord(s1[i]) - ord('a')] -= 1\n",
    "            cnt[ord(s2[i]) - ord('a')] += 1\n",
    "\n",
    "        sum = 0\n",
    "        big1, big2 = True, True\n",
    "        for i in range(25, -1, -1):\n",
    "            sum += cnt[i]\n",
    "            if big1 and sum > 0:\n",
    "                big1 = False\n",
    "            if big2 and sum < 0:\n",
    "                big2 = False\n",
    "            if not big1 and not big2:\n",
    "                return False\n",
    "        return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "from collections import defaultdict\n",
    "class Solution:\n",
    "    def checkIfCanBreak(self, s1: str, s2: str) -> bool:\n",
    "        def canBreak(s1: str, s2: str) -> bool:\n",
    "            \"\"\" Each char in s1 is larger than that in s2\n",
    "            \"\"\"\n",
    "            dict1 = defaultdict(int)\n",
    "            dict2 = defaultdict(int) \n",
    "            for char in s2:\n",
    "                dict1[char] += 1\n",
    "            for char in s1:\n",
    "                dict2[char] += 1\n",
    "            \n",
    "            # Greedy component\n",
    "            alpha = \"abcdefghijklmnopqrstuvwxyz\"\n",
    "            table = {ch: i for i, ch in enumerate(alpha)}\n",
    "            for ch in dict1:\n",
    "                pos = table[ch] \n",
    "                for i in range(pos, -1, -1):\n",
    "                    cur = alpha[i]\n",
    "                    # print(i, cur, ch)\n",
    "                    if dict1.get(ch, 0) == 0:\n",
    "                        break\n",
    "                    if dict2.get(cur, 0) != 0:\n",
    "                        if dict1[ch] < dict2[cur]:\n",
    "                            dict2[cur] -= dict1[ch]\n",
    "                            dict1[ch] = 0\n",
    "                        else:\n",
    "                            dict1[ch] -= dict2[cur]\n",
    "                            del dict2[cur]\n",
    "                # print(dict1, dict2)\n",
    "            return len(dict2) == 0\n",
    "\n",
    "        return canBreak(s1, s2) or canBreak(s2, s1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkIfCanBreak(self, s1: str, s2: str) -> bool:\n",
    "        c1 = Counter(s1)\n",
    "        c2 = Counter(s2)\n",
    "\n",
    "        chars = [chr(ord('a') + i) for i in range(26)]\n",
    "\n",
    "        acc1 = accumulate(c1[ch] for ch in chars)\n",
    "        acc2 = accumulate(c2[ch] for ch in chars)\n",
    "\n",
    "        acc1, acc2 = list(acc1), list(acc2)\n",
    "\n",
    "        return all(a1 <= a2 for a1, a2 in zip(acc1, acc2)) or \\\n",
    "               all(a1 >= a2 for a1, a2 in zip(acc1, acc2))\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkIfCanBreak(self, s1: str, s2: str) -> bool:\n",
    "        #将字符串按字母顺序排序\n",
    "        sorted_str1 = ''.join(sorted(s1))\n",
    "        sorted_str2 = ''.join(sorted(s2))\n",
    "\n",
    "        # 比较两个排序后的字符串\n",
    "        if sorted_str1 < sorted_str2 :\n",
    "           for i in range(1, len(sorted_str1)):\n",
    "                if sorted_str1[i] > sorted_str2[i]:\n",
    "                    return False\n",
    "        elif sorted_str1 > sorted_str2:\n",
    "            for i in range(1, len(sorted_str1)):\n",
    "                if sorted_str1[i] < sorted_str2[i]:\n",
    "                    return False\n",
    "        return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkIfCanBreak(self, s1: str, s2: str) -> bool:\n",
    "        def myfunc(s:str)->str:\n",
    "            l = list(s)\n",
    "            l.sort()\n",
    "            return \"\".join(l)\n",
    "        s1,s2 = myfunc(s1),myfunc(s2)\n",
    "        f1,f2 = True,True\n",
    "        for i in range(len(s1)):\n",
    "            if s1[i] < s2[i]:\n",
    "                f1 = False\n",
    "                break\n",
    "        for i in range(len(s1)):\n",
    "            if s2[i] < s1[i]:\n",
    "                f2 = False\n",
    "                break\n",
    "        if f1 or f2:\n",
    "            return True\n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkIfCanBreak(self, s1: str, s2: str) -> bool:\n",
    "        s1 = self.strSort(s1)\n",
    "        s2 = self.strSort(s2)\n",
    "        cur = 0\n",
    "        if s2 > s1:\n",
    "            s1, s2 = s2, s1\n",
    "        while cur < len(s1):\n",
    "            if s1[cur] < s2[cur]:\n",
    "                return False\n",
    "            cur += 1\n",
    "        return True\n",
    "    \n",
    "    \n",
    "\n",
    "    def strSort(self, s: str) -> str:\n",
    "        s = list(s)\n",
    "        s.sort(reverse=True)\n",
    "        return ''.join(s)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkIfCanBreak(self, s1: str, s2: str) -> bool:\n",
    "\n",
    "        chs1 = list(s1)\n",
    "        chs2 = list(s2)\n",
    "\n",
    "        chs1.sort()\n",
    "        chs2.sort()\n",
    "\n",
    "        return all(c1 >= c2 for c1, c2 in zip(chs1, chs2)) or \\\n",
    "               all(c1 <= c2 for c1, c2 in zip(chs1, chs2))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkIfCanBreak(self, s1: str, s2: str) -> bool:\n",
    "        s1 = sorted(s1)\n",
    "        s2 = sorted(s2)\n",
    "        return all(s1[i] >= s2[i] for i in range(len(s1))) or all(s1[i] <= s2[i] for i in range(len(s1)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkIfCanBreak(self, s1: str, s2: str) -> bool:\n",
    "        s1 = list(s1)\n",
    "        s2 = list(s2)\n",
    "        s1.sort()\n",
    "        s2.sort()\n",
    "        greater,less = 0,0\n",
    "        for i in range(len(s1)):\n",
    "            if s1[i] > s2[i]:\n",
    "                greater += 1\n",
    "            elif s1[i] < s2[i]:\n",
    "                less += 1\n",
    "        return greater == 0 or less == 0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\r\n",
    "    def checkIfCanBreak(self, s1: str, s2: str) -> bool:\r\n",
    "        s1 = sorted(s1)\r\n",
    "        s2 = sorted(s2)\r\n",
    "        n = len(s1)\r\n",
    "        flag = 0\r\n",
    "        for i in range(n):\r\n",
    "            if s1[i] > s2[i]:\r\n",
    "                flag |= 1\r\n",
    "            elif s1[i] < s2[i]:\r\n",
    "                flag |= 2\r\n",
    "        return flag != 3\r\n",
    "    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkIfCanBreak(self, s1: str, s2: str) -> bool:\n",
    "        chs1 = list(s1)\n",
    "        chs2 = list(s2)\n",
    "\n",
    "        chs1.sort()\n",
    "        chs2.sort()\n",
    "\n",
    "        return all(c1 >= c2 for c1, c2 in zip(chs1, chs2)) or all(c1 <= c2 for c1, c2 in zip(chs1, chs2))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkIfCanBreak(self, s1: str, s2: str) -> bool:\n",
    "        n =len(s1)\n",
    "        lst1 = list(s1)\n",
    "        lst2 = list(s2)\n",
    "        lst1.sort()\n",
    "        lst2.sort()\n",
    "        if all(lst1[i] >= lst2[i] for i in range(n)) or all(lst1[i] <= lst2[i] for i in range(n)):\n",
    "            return True\n",
    "        else:\n",
    "            return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkIfCanBreak(self, s1: str, s2: str) -> bool:\n",
    "        n = len(s1)\n",
    "        s1 = list(s1)\n",
    "        s2 = list(s2)\n",
    "        s1.sort()\n",
    "        s2.sort()\n",
    "        # print(s1, s2)\n",
    "        flag = None\n",
    "        for i in range(n):\n",
    "            if s1[i] == s2[i]:\n",
    "                continue\n",
    "            elif s1[i] > s2[i]:\n",
    "                if not flag:\n",
    "                    flag = 1\n",
    "                elif flag == -1:\n",
    "                    return False\n",
    "            else:\n",
    "                if not flag:\n",
    "                    flag = -1\n",
    "                elif flag == 1:\n",
    "                    return False\n",
    "        return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkIfCanBreak(self, s1: str, s2: str) -> bool:\n",
    "        ss1=sorted(s1)\n",
    "        ss2=sorted(s2)\n",
    "        l = len(s1)\n",
    "        ans = 0\n",
    "        for i in range(l):\n",
    "            if ss1[i]>ss2[i]:\n",
    "                if ans==-1:\n",
    "                    return False\n",
    "                ans=1\n",
    "            elif ss1[i]<ss2[i]:\n",
    "                if ans==1:\n",
    "                    return False\n",
    "                ans=-1\n",
    "        return True\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkIfCanBreak(self, s1: str, s2: str) -> bool:\n",
    "        s1_sorted = sorted(s1)\n",
    "        s2_sorted = sorted(s2)\n",
    "        \n",
    "        # 检查s1是否可以打破s2\n",
    "        can_s1_break_s2 = all(a >= b for a, b in zip(s1_sorted, s2_sorted))\n",
    "        \n",
    "        # 检查s2是否可以打破s1\n",
    "        can_s2_break_s1 = all(a >= b for a, b in zip(s2_sorted, s1_sorted))\n",
    "        \n",
    "        return can_s1_break_s2 or can_s2_break_s1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkIfCanBreak(self, s1: str, s2: str) -> bool:\n",
    "        s1_sorted = sorted(s1)\n",
    "        s2_sorted = sorted(s2)\n",
    "        \n",
    "        # 检查s1是否可以打破s2\n",
    "        can_s1_break_s2 = all(a >= b for a, b in zip(s1_sorted, s2_sorted))\n",
    "        \n",
    "        # 检查s2是否可以打破s1\n",
    "        can_s2_break_s1 = all(a >= b for a, b in zip(s2_sorted, s1_sorted))\n",
    "        \n",
    "        return can_s1_break_s2 or can_s2_break_s1\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkIfCanBreak(self, s1: str, s2: str) -> bool:\n",
    "        s1 = sorted(s1)\n",
    "        s2 = sorted(s2)\n",
    "        return all(c1 >= c2 for c1, c2 in zip(s1, s2)) or all(c1 <= c2 for c1, c2 in zip(s1, s2))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkIfCanBreak(self, s1: str, s2: str) -> bool:\n",
    "        return all(x >= y for x,y in zip(sorted(s1),sorted(s2))) or all(x >= y for x,y in zip(sorted(s2),sorted(s1))) "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkIfCanBreak(self, s1: str, s2: str) -> bool:\n",
    "\n",
    "        chs1 = list(s1)\n",
    "        chs2 = list(s2)\n",
    "\n",
    "        chs1.sort()\n",
    "        chs2.sort()\n",
    "\n",
    "        return all(c1 >= c2 for c1, c2 in zip(chs1, chs2)) or \\\n",
    "               all(c1 <= c2 for c1, c2 in zip(chs1, chs2))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkIfCanBreak(self, s1: str, s2: str) -> bool:\n",
    "        n=len(s1)\n",
    "        a,b=sorted(s1,reverse=True),sorted(s2,reverse=True)\n",
    "        return all(a[i]>=b[i] for i in range(n)) or all(b[i]>=a[i] for i in range(n))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkIfCanBreak(self, s1: str, s2: str) -> bool:\n",
    "        #贪心地排列\n",
    "        n=len(s1)\n",
    "        a,b=sorted(s1,reverse=True),sorted(s2,reverse=True)\n",
    "        return all(a[i]>=b[i] for i in range(n)) or all(b[i]>=a[i] for i in range(n))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkIfCanBreak(self, s1: str, s2: str) -> bool:\n",
    "        s1 = sorted(s1)\n",
    "        s2 = sorted(s2)\n",
    "        big = None\n",
    "        for c1, c2 in zip(s1, s2):\n",
    "            if c1 > c2:\n",
    "                if big == None:\n",
    "                    big = True\n",
    "                elif big == False:\n",
    "                    return False\n",
    "            elif c2 > c1:\n",
    "                if big == None:\n",
    "                    big = False\n",
    "                elif big == True:\n",
    "                    return False\n",
    "                    \n",
    "        return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkIfCanBreak(self, s1: str, s2: str) -> bool:\n",
    "        ls1,ls2 = list(s1),list(s2)\n",
    "        ls1.sort()\n",
    "        ls2.sort()\n",
    "        flag1,flag2 = False,False\n",
    "        for i,j in zip(ls1,ls2):\n",
    "            if i>j:\n",
    "                flag1 = True\n",
    "            elif i<j:\n",
    "                flag2 = True\n",
    "            else:\n",
    "                continue\n",
    "        return not (flag1 and flag2)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkIfCanBreak(self, s1: str, s2: str) -> bool:\n",
    "        s1 = sorted(s1)\n",
    "        s2 = sorted(s2)\n",
    "        big = None\n",
    "        for c1, c2 in zip(s1, s2):\n",
    "            if c1 == c2:\n",
    "                continue\n",
    "            now = c1 > c2\n",
    "            if big == None:\n",
    "                big = now\n",
    "            elif big != now:\n",
    "                return False\n",
    "                    \n",
    "        return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkIfCanBreak(self, s1: str, s2: str) -> bool:\n",
    "        arr1, arr2 = list(s1), list(s2)\n",
    "        arr1.sort()\n",
    "        arr2.sort()\n",
    "        a, b = 0, 0\n",
    "        for i in range(0, len(s1)):\n",
    "            if arr1[i] > arr2[i]:\n",
    "                a += 1\n",
    "            elif arr1[i] < arr2[i]:\n",
    "                b += 1\n",
    "        return a == 0 or b == 0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkIfCanBreak(self, s1: str, s2: str) -> bool:\n",
    "        s1 = sorted(s1)\n",
    "        s2 = sorted(s2)\n",
    "        flag1 = True\n",
    "        flag2 = True\n",
    "        for i in range(len(s1)):\n",
    "            if s1[i] < s2[i]:\n",
    "                flag1 = False\n",
    "            if s1[i] > s2[i]:\n",
    "                flag2 = False\n",
    "        return flag1 or flag2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "\n",
    "\n",
    "class Solution:\n",
    "    def checkIfCanBreak(self, s1: str, s2: str) -> bool:\n",
    "\n",
    "        chs1 = list(s1)\n",
    "        chs2 = list(s2)\n",
    "\n",
    "        chs1.sort()\n",
    "        chs2.sort()\n",
    "\n",
    "        return all(c1 >= c2 for c1, c2 in zip(chs1, chs2)) or \\\n",
    "               all(c1 <= c2 for c1, c2 in zip(chs1, chs2))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkIfCanBreak(self, s1: str, s2: str) -> bool:\n",
    "\n",
    "        s1 = sorted(s1)\n",
    "        s2 = sorted(s2)\n",
    "\n",
    "        return all(x >=y for x,y in zip(s1,s2)) or all(x>=y for x,y in zip(s2,s1))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkIfCanBreak(self, s1: str, s2: str) -> bool:\n",
    "        \n",
    "        def cmp(a, b):\n",
    "            ln = len(a)\n",
    "            a = sorted(a)\n",
    "            b = sorted(b)\n",
    "            if all(a[i] >= b[i] for i in range(ln)):\n",
    "                return True \n",
    "            return False \n",
    "        \n",
    "        return cmp(s1, s2) or cmp(s2, s1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkIfCanBreak(self, s1: str, s2: str) -> bool:\n",
    "        list1 = list(s1)\n",
    "        list2 = list(s2)\n",
    "        list1.sort()\n",
    "        list2.sort()\n",
    "        return all(a <= b for a, b in zip(list1, list2)) \\\n",
    "            or all(a >= b for a, b in zip(list1, list2))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkIfCanBreak(self, s1: str, s2: str) -> bool:\n",
    "        s1 = list(s1)\n",
    "        s2 = list(s2)\n",
    "        s1.sort()\n",
    "        s2.sort()\n",
    "        counts1,counts2 = 0,0\n",
    "        for i in range(len(s1)):\n",
    "            if ord(s1[i]) - ord('a') >= ord(s2[i]) - ord('a'):\n",
    "                counts1 += 1\n",
    "            if ord(s2[i]) - ord('a') >= ord(s1[i]) - ord('a'):\n",
    "                counts2 += 1\n",
    "        if counts1 == len(s1) or counts2 == len(s2):\n",
    "            return True\n",
    "        else:\n",
    "            return False\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkIfCanBreak(self, s1: str, s2: str) -> bool:\n",
    "        n = len(s1)\n",
    "        numa = [ord(c) for c in s1]\n",
    "        numb = [ord(c) for c in s2]\n",
    "        numa.sort()\n",
    "        numb.sort()\n",
    "\n",
    "        flag = True\n",
    "        for i in range(n):\n",
    "            if numa[i] < numb[i]:\n",
    "                flag = False\n",
    "        if flag:\n",
    "            return True\n",
    "        \n",
    "        flag = True\n",
    "        for i in range(n):\n",
    "            if numa[i] > numb[i]:\n",
    "                flag = False\n",
    "        if flag:\n",
    "            return True\n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkIfCanBreak(self, s1: str, s2: str) -> bool:\n",
    "        s1_sorted = sorted(s1)\n",
    "        s2_sorted = sorted(s2)\n",
    "        \n",
    "        # 检查s1是否可以打破s2\n",
    "        can_s1_break_s2 = all(a >= b for a, b in zip(s1_sorted, s2_sorted))\n",
    "        \n",
    "        # 检查s2是否可以打破s1\n",
    "        can_s2_break_s1 = all(a >= b for a, b in zip(s2_sorted, s1_sorted))\n",
    "        \n",
    "        return can_s1_break_s2 or can_s2_break_s1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkIfCanBreak(self, s1: str, s2: str) -> bool:\n",
    "        s1 = sorted(list(s1))\n",
    "        s2 = sorted(list(s2))\n",
    "        flag = 0\n",
    "        for i in range(len(s1)):\n",
    "            if s1[i] > s2[i]:\n",
    "                if not flag:    flag = 1\n",
    "                elif flag == -1:    return False\n",
    "            elif s1[i] < s2[i]:\n",
    "                if not flag:    flag = -1\n",
    "                elif flag == 1:     return False\n",
    "        return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkIfCanBreak(self, s1: str, s2: str) -> bool:\n",
    "        ss1=sorted(s1)\n",
    "        ss2=sorted(s2)\n",
    "        l = len(s1)\n",
    "        ans = []\n",
    "        for i in range(l):\n",
    "            if ss1[i]>ss2[i]:\n",
    "                ans.append(1)\n",
    "            elif ss1[i]<ss2[i]:\n",
    "                ans.append(-1)\n",
    "            else:\n",
    "                ans.append(0)\n",
    "        if 1 in ans and -1 in ans:\n",
    "            return False\n",
    "        else:\n",
    "            return True\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkIfCanBreak(self, s1: str, s2: str) -> bool:\n",
    "        s1 = sorted(list(s1))\n",
    "        s2 = sorted(list(s2))\n",
    "        return all(s1[i] >= s2[i] for i in range(len(s1))) or \\\n",
    "            all(s2[i] >= s1[i] for i in range(len(s1)))\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkIfCanBreak(self, s1: str, s2: str) -> bool:\n",
    "        m = sorted(s1)\n",
    "        n = sorted(s2)\n",
    "        l = len(m)\n",
    "        max_count = 0\n",
    "        min_count = 0\n",
    "        print(m,n)\n",
    "        for i in range(l):\n",
    "            if m[i] >= n[i]:\n",
    "                max_count += 1\n",
    "            if m[i] <= n[i]:\n",
    "                min_count += 1\n",
    "        print(min_count,max_count)\n",
    "        return True if min_count == l or max_count == l else False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkIfCanBreak(self, s1: str, s2: str) -> bool:\n",
    "        mydict = {\"a\":1,\"b\":2,\"c\":3,\"d\":4,\"e\":5,\"f\":6,\"g\":7,\"h\":8,\"i\":9,\"j\":10,\"k\":11,\"l\":12,\"m\":13,\"n\":14,\"o\":15,\"p\":16,\"q\":17,\"r\":18,\"s\":19,\"t\":20,\"u\":21,\"v\":22,\"w\":23,\"x\":24,\"y\":25,\"z\":26}\n",
    "        list1 = list(s1)\n",
    "        list1.sort()\n",
    "        list2 = list(s2)\n",
    "        list2.sort()\n",
    "        if all([mydict[list1[i]] >= mydict[list2[i]] for i in range(len(s1))]) or all([mydict[list1[i]] <= mydict[list2[i]] for i in range(len(s1))]):\n",
    "            return (True)\n",
    "        return (False)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkIfCanBreak(self, s1: str, s2: str) -> bool:\n",
    "        s1 = sorted(list(s1))\n",
    "        s2 = sorted(list(s2))\n",
    "        return all(a >= b for a, b in zip(s1, s2)) or all(a <= b for a, b in zip(s1, s2))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkIfCanBreak(self, s1: str, s2: str) -> bool:\n",
    "        list1 = sorted(list(s1))\n",
    "        list2 = sorted(list(s2))\n",
    "\n",
    "        s1_small = True\n",
    "        s2_small = True\n",
    "        for ch1, ch2 in zip(list1, list2):\n",
    "            if ord(ch1) > ord(ch2):\n",
    "                s1_small = False\n",
    "            if ord(ch2) > ord(ch1):\n",
    "                s2_small = False\n",
    "            \n",
    "            if not s1_small and not s2_small:\n",
    "                return False\n",
    "        \n",
    "        return True\n",
    "        \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkIfCanBreak(self, s1: str, s2: str) -> bool:\n",
    "        return all(x>=y for x,y in zip(sorted(list(s1)),sorted(list(s2)))) or all(x<=y for x,y in zip(sorted(list(s1)),sorted(list(s2))))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkIfCanBreak(self, s1: str, s2: str) -> bool:\n",
    "        # 返回a能否打破b\n",
    "        def beat(a, b):\n",
    "            for i in range(n):\n",
    "                if a[i] < b[i]:\n",
    "                    return False\n",
    "            return True\n",
    "\n",
    "        a, b = sorted(list(s1)), sorted(list(s2))\n",
    "        n = len(s1)\n",
    "        return beat(a, b) or beat(b, a)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkIfCanBreak(self, s1: str, s2: str) -> bool:\n",
    "        if len(s1) != len(s2):\n",
    "            return False\n",
    "        lst1 = []\n",
    "        lst2 = []\n",
    "        for i in range(len(s1)):\n",
    "            lst1.append(int(ord(s1[i])))\n",
    "            lst2.append(int(ord(s2[i])))\n",
    "        lst1.sort()\n",
    "        lst2.sort()\n",
    "        flag = True\n",
    "        print(lst1,lst2)\n",
    "        if sum(lst1) >= sum(lst2):\n",
    "            for i in range(len(lst1)):\n",
    "                if lst1[i]<lst2[i]:\n",
    "                    flag = False\n",
    "        if sum(lst1) <= sum(lst2):\n",
    "            for i in range(len(lst1)):\n",
    "                if lst1[i]>lst2[i]:\n",
    "                    flag = False\n",
    "        return flag"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def isValidSequence(self, root: Optional[TreeNode], arr: List[int]) -> bool:\n",
    "        return self.check(root, arr, 0)\n",
    "\n",
    "    def check(self, root, arr, i):\n",
    "        if root is None or i >= len(arr):\n",
    "            return False \n",
    "\n",
    "        if root.left is None and root.right is None:\n",
    "            return arr[i] == root.val and i == len(arr) - 1\n",
    "\n",
    "        if root.val == arr[i]:\n",
    "            return self.check(root.left, arr, i + 1) \\\n",
    "                    or self.check(root.right, arr, i + 1)\n",
    "        return False\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkString(self, s: str) -> bool:\n",
    "        i = 0\n",
    "\n",
    "        while i < len(s) and s[i] == \"a\":\n",
    "            i += 1\n",
    "        if i == len(s):\n",
    "            return True\n",
    "        \n",
    "        while i < len(s) and s[i] == \"b\":\n",
    "            i += 1\n",
    "\n",
    "        return i == len(s)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkString(self, s: str) -> bool:\n",
    "        loc_a = -1\n",
    "        loc_b = -1\n",
    "        i = 0\n",
    "        for a in s:\n",
    "            if s[i] == \"a\":\n",
    "                loc_a = i\n",
    "            elif s[i] == \"b\" and loc_b == -1:\n",
    "               loc_b = i\n",
    "            i += 1 \n",
    "        if loc_b > loc_a:\n",
    "            return True\n",
    "        elif loc_a == -1 or loc_b == -1:\n",
    "            return True\n",
    "        else:\n",
    "            return False           "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkString(self, s: str) -> bool:\n",
    "        pa = s[::-1].find('a')\n",
    "        if pa==-1:\n",
    "            return True\n",
    "        pa = len(s)-1-pa\n",
    "        pb = s.find('b')\n",
    "        if pb==-1:\n",
    "            return True\n",
    "        if pa<pb:\n",
    "            return True\n",
    "        else:\n",
    "            return False\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkString(self, s: str) -> bool:\n",
    "        n = len(s)\n",
    "        for i in range(0, n - 1):\n",
    "            if s[i] == 'b' and s[i + 1] == 'a':\n",
    "                return False\n",
    "        return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkString(self, s: str) -> bool:\n",
    "        a = False\n",
    "        for i in s:\n",
    "            if not a and i == 'b':\n",
    "                a = True\n",
    "            if a:\n",
    "                if i == 'a':\n",
    "                    return False\n",
    "        return True\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkString(self, s: str) -> bool:\n",
    "        if 'b' not in s or 'a' not in s:\n",
    "            return True\n",
    "        return len(s)-1-s[::-1].index('a')<s.index('b')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkString(self, s: str) -> bool:\n",
    "        if \"ba\" in s:\n",
    "            return False\n",
    "        else:\n",
    "            return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkString(self, s: str) -> bool:\n",
    "        counta=s.count('a')\n",
    "        countb=s.count('b')\n",
    "        if s==counta*'a'+countb*'b':\n",
    "            return True\n",
    "        else:\n",
    "            return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkString(self, s: str) -> bool:\n",
    "        return list(s) == sorted(s)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkString(self, s: str) -> bool:\n",
    "        u=s.count('a')\n",
    "        if 'a' not in s:\n",
    "            return True\n",
    "        else:\n",
    "            for i in range(0,u):\n",
    "                if s[i]=='b':\n",
    "                    return False\n",
    "        return True\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkString(self, s: str) -> bool:\n",
    "        res1=s.rfind(\"a\")\n",
    "        res2=s.find(\"b\")\n",
    "        if res2>res1 or res2==-1:\n",
    "            return True\n",
    "        else:\n",
    "            return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkString(self, s: str) -> bool:\n",
    "        idxa, idxb = float('-inf'), float('inf')\n",
    "        for k,v in enumerate(s):\n",
    "            if v == 'a': idxa = max(idxa, k)\n",
    "            else: idxb = min(idxb, k)\n",
    "        return idxa < idxb"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkString(self, s: str) -> bool:\n",
    "        n = len(s)\n",
    "        have_b = False\n",
    "        for i in range(0, n):\n",
    "            if s[i] == 'b':\n",
    "                have_b = True\n",
    "            elif s[i] == 'a':\n",
    "                if have_b:\n",
    "                    return False\n",
    "        return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkString(self, s: str) -> bool:\n",
    "        s = list(s)\n",
    "        if 'b' in s:\n",
    "            idx = s.index('b')\n",
    "            for i in range(idx+1,len(s)):\n",
    "                if s[i] == 'a':\n",
    "                    return False\n",
    "            return True\n",
    "        else:\n",
    "            return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkString(self, s: str) -> bool:\n",
    "        posa = posb = -1\n",
    "        for i,char in enumerate(s):\n",
    "            if char == \"a\":\n",
    "                posa = i\n",
    "                if (posa > posb) & (posb > -1):\n",
    "                    return False\n",
    "            if (char == \"b\") & (posb == -1):\n",
    "                posb = i\n",
    "        return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkString(self, s: str) -> bool:\n",
    "        n = len(s)\n",
    "        if \"a\" not in s:\n",
    "            return True\n",
    "        i = 0\n",
    "        while i < n and s[i] == \"a\":\n",
    "            i += 1\n",
    "        while i < n and s[i] == \"b\":\n",
    "            i += 1\n",
    "        return i == n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkString(self, s: str) -> bool:\n",
    "        label1=0\n",
    "        ls=len(s)\n",
    "        label2=ls-1\n",
    "        co=0\n",
    "        coo=0\n",
    "        for i in range(ls):\n",
    "            if(label2==ls-1 and s[i]=='b' and co==0):\n",
    "                label2=i\n",
    "                co=1\n",
    "            if(label1==0 and s[-i-1]=='a' and coo==0):\n",
    "                label1=ls-i-1\n",
    "                coo=1\n",
    "        return label1<=label2\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkString(self, s: str) -> bool:\n",
    "        return s.find('ba') == -1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkString(self, s: str) -> bool:\n",
    "        # 拿到第一个b的下标。\n",
    "        # 从这个位置遍历到尾\n",
    "        # 如果有任何一个a则false。并且停止\n",
    "        try:\n",
    "            tmp_index = s.index(\"b\")\n",
    "        except:\n",
    "            return True\n",
    "        res = True\n",
    "\n",
    "        for i in s[tmp_index:]:\n",
    "            if i == \"a\":\n",
    "                return False\n",
    "        return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkString(self, s: str) -> bool:\n",
    "        flag = 0\n",
    "        for x in s:\n",
    "            if x == 'b':\n",
    "                flag = 1\n",
    "            else:\n",
    "                if flag:\n",
    "                    return False\n",
    "        return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkString(self, s: str) -> bool:\n",
    "        return \"ba\" not in s "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkString(self, s):\n",
    "        if \"ba\" in s: return False\n",
    "        else: return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkString(self, s: str) -> bool:\n",
    "        return \"ba\" not in s or len(set(s)) == 1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkString(self, s: str) -> bool:\n",
    "        if 'a' not in s:\n",
    "            return True\n",
    "        count = 0\n",
    "        for i in range(len(s)-1):\n",
    "           if s[i] > s[i+1]:\n",
    "               return False\n",
    "        \n",
    "        return True\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkString(self, s: str) -> bool:\n",
    "        n = len(s)\n",
    "        lasta = -1\n",
    "        firstb = n\n",
    "        for i in range(n):\n",
    "            if s[i] == 'a':\n",
    "                lasta = max(lasta,i)\n",
    "            else:\n",
    "                firstb = min(firstb,i)\n",
    "        return lasta<firstb"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkString(self, s: str) -> bool:\n",
    "        n = len(s)\n",
    "        i = 0\n",
    "        while i < n and s[i] == \"a\":\n",
    "            i += 1\n",
    "        while i < n and s[i] == \"b\":\n",
    "            i += 1\n",
    "        return i == n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkString(self, s: str) -> bool:\n",
    "        if all(_ == 'a' for _ in s):\n",
    "            return True\n",
    "        return s.find('b') > s.rfind('a')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkString(self, s: str) -> bool:\n",
    "        haveb = False\n",
    "        for i in s:\n",
    "            if i == 'b':\n",
    "                haveb = True\n",
    "            if i == 'a' and haveb:\n",
    "                return False\n",
    "\n",
    "        return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkString(self, s: str) -> bool:\n",
    "        return ''.join(sorted(s))==s"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkString(self, s: str) -> bool:\n",
    "        if 'a' not in s or 'b' not in s:\n",
    "            return True\n",
    "        dex = s.index(\"b\")\n",
    "        lis = []\n",
    "        for i in range(len(s)):\n",
    "            if s[i] == \"a\":\n",
    "                if i > dex:\n",
    "                    return False\n",
    "        return True\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkString(self, s: str) -> bool:\n",
    "        for i in range(len(s)-1):\n",
    "            if s[i] > s[i+1]:\n",
    "                return False\n",
    "        return True\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkString(self, s: str) -> bool:\n",
    "        '''\n",
    "        haveb = False\n",
    "        for i in s:\n",
    "            if i == 'b':\n",
    "                haveb = True\n",
    "            if i == 'a' and haveb:\n",
    "                return False\n",
    "\n",
    "        return True\n",
    "        '''\n",
    "\n",
    "        return list(s) == sorted(s)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkString(self, s: str) -> bool:\n",
    "        return list(s)==sorted(s)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkString(self, s: str) -> bool:\n",
    "        return re.match(r'^a*b*$', s) != None"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkString(self, s: str) -> bool:\n",
    "        return s.rfind('a') < s.find('b') or 'b' not in s "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkString(self, s: str) -> bool:\n",
    "        for i in range(len(s)-1):\n",
    "            if (s[i] == \"b\") & (s[i+1] == \"a\"):\n",
    "                return False\n",
    "        return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkString(self, s: str) -> bool:\n",
    "        flag = False\n",
    "\n",
    "        for i in s:\n",
    "            if i == \"b\":\n",
    "                flag = True\n",
    "            if i == \"a\" and flag:\n",
    "                return False\n",
    "        return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "\n",
    "class Solution:\n",
    "    def checkString(self, s: str) -> bool:\n",
    "        return list(s) == sorted(s)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkString(self, s: str) -> bool:\n",
    "        # if there is no 'a', return True\n",
    "        if s.count('a') == 0 or s.count('b') == 0:\n",
    "            return True\n",
    "        # find the max index of a and min index of b\n",
    "        \n",
    "        index_a = len(s) - (s[::-1].index('a')) - 1\n",
    "        index_b = s.index('b')\n",
    "        # print(index_a)\n",
    "        # print(index_b)\n",
    "        return index_a < index_b\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkString(self, s: str) -> bool:\n",
    "        if 'b' not in s:\n",
    "            return True\n",
    "        else:\n",
    "            idx = s.find('b')\n",
    "            remain = s[idx+1:]\n",
    "            if 'a' not in remain:\n",
    "                return True\n",
    "            else:\n",
    "                return False\n",
    "            "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkString(self, s: str) -> bool:\n",
    "        for i in range(len(s)):\n",
    "            if s[i]==\"b\":\n",
    "                for j in s[i::]:\n",
    "                    if j ==\"a\":\n",
    "                        return False\n",
    "        return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# class Solution:\n",
    "#     def checkString(self, s: str) -> bool:\n",
    "#         n=len(s)\n",
    "#         a,b=-1,n\n",
    "#         for i,ch in enumerate(s):\n",
    "#             if ch==\"a\":\n",
    "#                 a=i \n",
    "#             else:\n",
    "#                 if b>i:\n",
    "#                     b=i \n",
    "#         return b-a>0\n",
    "\n",
    "\n",
    "### 官2：str.find\n",
    "class Solution:\n",
    "    def checkString(self,s):\n",
    "        return s.find(\"ba\")==-1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkString(self, s: str) -> bool:\n",
    "        b = 0\n",
    "        for i in s:\n",
    "            if i == 'b':\n",
    "                b = 1\n",
    "            if (i == 'a') and (b == 1):\n",
    "                return False\n",
    "        return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkString(self, s: str) -> bool:\n",
    "        for i in range(len(s)-1):\n",
    "            if s[i] > s[i+1]:\n",
    "                return False\n",
    "        return True\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkString(self, s: str) -> bool:\n",
    "        ib = len(s)\n",
    "        for i, q in enumerate(s):\n",
    "            if q == 'b':\n",
    "                ib = min(ib, i)\n",
    "            if q == 'a' and i > ib:\n",
    "                return False\n",
    "        return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkString(self, s: str) -> bool:\n",
    "        if 'a' not in s or 'b' not in s:\n",
    "            return True\n",
    "        return s.rfind('a') < s.find('b')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkString(self, s: str) -> bool:\n",
    "        change = 0\n",
    "        c = 'a'\n",
    "        for i in range(len(s)):\n",
    "            if c != s[i]:\n",
    "                change += 1\n",
    "                if change >= 2:\n",
    "                    return False\n",
    "                c = s[i]\n",
    "        return True\n",
    "            \n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkString(self, s: str) -> bool:\n",
    "        return \"ba\" not in s "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkString(self, s: str) -> bool:\n",
    "        flag = True\n",
    "        for word in s:\n",
    "            if word==\"b\": \n",
    "                flag=False\n",
    "            if word=='a' and flag==False:\n",
    "                return False\n",
    "        return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkString(self, s: str) -> bool:\n",
    "        if 'b' not in s:\n",
    "            return True\n",
    "        for i in s[s.index('b'):]:\n",
    "            if i=='a':\n",
    "                return  False\n",
    "        return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkString(self, s: str) -> bool:\n",
    "        return \"ba\" not in s "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkString(self, s: str) -> bool:\n",
    "        return s.find('ba') == -1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkString(self, s: str) -> bool:\n",
    "        bong = ''\n",
    "        for data in s:\n",
    "            if data == 'a' and bong == 'b' :\n",
    "                return False\n",
    "            elif data == 'b':\n",
    "                bong = 'b'\n",
    "        return True\n",
    "       "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkString(self, s: str) -> bool:\n",
    "        return s.find(\"ba\") == -1\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkString(self, s: str) -> bool:\n",
    "        return \"ba\" not in s"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkString(self, s: str) -> bool:\n",
    "        a,b =0,0\n",
    "        for c in s:\n",
    "            if c =='a':\n",
    "                if b:\n",
    "                    return False\n",
    "                a+=1\n",
    "            else:\n",
    "                b+=1\n",
    "        return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkString(self, s: str) -> bool:\n",
    "        idxa, idxb = float('-inf'), float('inf')\n",
    "        for k,v in enumerate(s):\n",
    "            if v == 'a': idxa = max(idxa, k)\n",
    "            else: idxb = min(idxb, k)\n",
    "        return idxa < idxb"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkString(self, s: str) -> bool:\n",
    "\n",
    "        left, right = 0, len(s)-1\n",
    "\n",
    "        if len(set(s)) == 1:\n",
    "            return True\n",
    "\n",
    "        while right > 0:\n",
    "            if s[right] == 'a':\n",
    "                break\n",
    "            else:\n",
    "                right -= 1\n",
    "\n",
    "        while right > left:\n",
    "            if s[left] == 'b':\n",
    "                return False\n",
    "            left += 1\n",
    "        \n",
    "        return True\n",
    "\n",
    "        # from the last a, start to go left to find if there is an 'b'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkString(self, s: str) -> bool:\n",
    "        a=0\n",
    "        for i in s:\n",
    "            if i=='b':\n",
    "                a=1\n",
    "            if i=='a' and a==1:\n",
    "                return False\n",
    "        return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkString(self, s: str) -> bool:\n",
    "        return \"ba\" not in s"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkString(self, s: str) -> bool:\n",
    "        find=False\n",
    "        for ch in s:\n",
    "            if ch==\"b\":\n",
    "                find=True\n",
    "            if find and ch==\"a\":\n",
    "                return False\n",
    "        return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkString(self, s: str) -> bool:\n",
    "        idxa, idxb = float('-inf'), float('inf')\n",
    "        for k,v in enumerate(s):\n",
    "            if v == 'a': idxa = max(idxa, k)\n",
    "            else: idxb = min(idxb, k)\n",
    "        return idxa < idxb"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkString(self, s: str) -> bool:\n",
    "        for i in range(len(s)-1):\n",
    "            if s[i] == 'b' and s[i+1] == 'a':\n",
    "                return False\n",
    "        return True\n",
    "       "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkString(self, s: str) -> bool:\n",
    "        bAppear = False\n",
    "        for i in s:\n",
    "            if i == 'a' and bAppear:\n",
    "                return False\n",
    "            if i == 'b':\n",
    "                bAppear = True\n",
    "        \n",
    "        return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkString(self, s: str) -> bool:\n",
    "        a_index = -1\n",
    "        b_index = len(s)\n",
    "        for i, ss in enumerate(s):\n",
    "            if ss == 'a':\n",
    "                a_index = i\n",
    "            else:\n",
    "                b_index = min(b_index, i)\n",
    "        return a_index < b_index"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkString(self, s: str) -> bool:\n",
    "        return list(s) == sorted(s)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkString(self, s: str) -> bool:\n",
    "        if 'a' not in s or 'b' not in s:\n",
    "            return True\n",
    "        return s.rfind('a') < s.find('b')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkString(self, s: str) -> bool:\n",
    "        meet_a = False\n",
    "\n",
    "        for i in range(len(s) -1 ,-1,-1):\n",
    "            if s[i] == 'a':\n",
    "                meet_a = True\n",
    "            elif s[i] == 'b':\n",
    "                if meet_a:\n",
    "                    return False\n",
    "        \n",
    "        return not meet_a if meet_a == False else meet_a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkString(self, s: str) -> bool:\n",
    "        index=-1\n",
    "        for i in range(len(s)):\n",
    "            if s[i]=='b':\n",
    "                index=i\n",
    "                break\n",
    "        if index==-1:\n",
    "            return True\n",
    "        for j in range(index,len(s)):\n",
    "            if s[j]=='a':\n",
    "                return False\n",
    "        return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkString(self, s: str) -> bool:\n",
    "        return s.count('a') == s.rfind('a') + 1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkString(self, s: str) -> bool:\n",
    "      flag = False\n",
    "      for ch in s:\n",
    "        if ch == \"b\":\n",
    "          flag = True\n",
    "        elif flag:\n",
    "          return False\n",
    "      return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkString(self, s: str) -> bool:\n",
    "        # 题目可转化为第一个b之后是否存在a，若存在则False\n",
    "        flag = 1\n",
    "        start = 1\n",
    "        for i in range(len(s)):\n",
    "            if not start and s[i] == 'a':\n",
    "                flag = 0\n",
    "                break\n",
    "            if start and s[i] == 'b':\n",
    "                start = 0\n",
    "        \n",
    "        return flag == 1\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def checkString(self, s: str) -> bool:\n",
    "        return list(s) == sorted(s)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isCovered(self, ranges: List[List[int]], left: int, right: int) -> bool:\n",
    "        def check(ranges,i):\n",
    "            for ra in ranges:\n",
    "                if i<=ra[1] and i>=ra[0]:\n",
    "                    return True\n",
    "            return False\n",
    "        for i in range(left,right+1):\n",
    "            if not check(ranges,i):\n",
    "                return False\n",
    "        return True\n",
    "            "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def possiblyEquals(self, s1: str, s2: str) -> bool:\n",
    "\n",
    "        def check(st):\n",
    "            if len(st) == 1:\n",
    "                return [int(st)]\n",
    "            if len(st) == 2:\n",
    "                return [int(st), int(st[0]) + int(st[1])]\n",
    "            return [int(st), int(st[:2]) + int(st[2]), int(st[0]) + int(st[1:]), int(st[0]) + int(st[1]) + int(st[2])]\n",
    "\n",
    "        def depart(s):\n",
    "            k = len(s)\n",
    "            i = 0\n",
    "            res = []\n",
    "            while i < k:\n",
    "                if s[i].isnumeric():\n",
    "                    cur = \"\"\n",
    "                    while i < k and s[i].isnumeric():\n",
    "                        cur += s[i]\n",
    "                        i += 1\n",
    "                    res.append([str(x) for x in check(cur)])\n",
    "                else:\n",
    "                    res.append([s[i]])\n",
    "                    i += 1\n",
    "            post = []\n",
    "            for ls in res:\n",
    "                post.append(max(int(w) if w.isnumeric() else 1 for w in ls))\n",
    "            return res, list(accumulate(post, initial=0))\n",
    "\n",
    "        lst1, pre1 = depart(s1)\n",
    "        lst2, pre2 = depart(s2)\n",
    "        m, n = len(lst1), len(lst2)\n",
    "\n",
    "\n",
    "        @lru_cache(None)\n",
    "        def dfs(i, j, x):\n",
    "            if pre2[-1] - pre2[j] < x:\n",
    "                return False\n",
    "            if pre1[-1] - pre1[i] < -x:\n",
    "                return False\n",
    "            \n",
    "            if x == 0:\n",
    "                if i == m and j == n:\n",
    "                    return True\n",
    "                if i == m or j == n:\n",
    "                    return False\n",
    "                for a in lst1[i]:\n",
    "                    for b in lst2[j]:\n",
    "                        if a.isnumeric() and b.isnumeric():\n",
    "                            if dfs(i + 1, j + 1, int(a) - int(b)):\n",
    "                                return True\n",
    "                        elif not a.isnumeric() and not b.isnumeric():\n",
    "                            if a == b and dfs(i + 1, j + 1, 0):\n",
    "                                return True\n",
    "                        elif a.isnumeric() and not b.isnumeric():\n",
    "                            if dfs(i + 1, j + 1, int(a) - 1):\n",
    "                                return True\n",
    "                        else:\n",
    "                            if dfs(i + 1, j + 1, 1 - int(b)):\n",
    "                                return True\n",
    "                return False\n",
    "            elif x > 0:\n",
    "                if j == n:\n",
    "                    return False\n",
    "                for b in lst2[j]:\n",
    "                    if b.isnumeric() and dfs(i, j + 1, x - int(b)):\n",
    "                        return True\n",
    "                    if not b.isnumeric() and dfs(i, j + 1, x - 1):\n",
    "                        return True\n",
    "            else:\n",
    "                if i == m:\n",
    "                    return False\n",
    "                for a in lst1[i]:\n",
    "                    if a.isnumeric() and dfs(i + 1, j, x + int(a)):\n",
    "                        return True\n",
    "                    if not a.isnumeric() and dfs(i + 1, j, x + 1):\n",
    "                        return True\n",
    "            return\n",
    "\n",
    "        return dfs(0, 0, 0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def possiblyEquals(self, s1: str, s2: str) -> bool:\n",
    "\n",
    "        def check(st):\n",
    "            if len(st) == 1:\n",
    "                return [int(st)]\n",
    "            if len(st) == 2:\n",
    "                return [int(st), int(st[0])+int(st[1])]\n",
    "            return [int(st), int(st[:2])+int(st[2]), int(st[0])+int(st[1:]), int(st[0])+int(st[1])+int(st[2])]\n",
    "\n",
    "        def depart(s):\n",
    "            k = len(s)\n",
    "            i = 0\n",
    "            res = []\n",
    "            while i < k:\n",
    "                if s[i].isnumeric():\n",
    "                    cur = \"\"\n",
    "                    while i < k and s[i].isnumeric():\n",
    "                        cur += s[i]\n",
    "                        i += 1\n",
    "                    res.append([str(x) for x in check(cur)])\n",
    "                else:\n",
    "                    res.append([s[i]])\n",
    "                    i += 1\n",
    "            return res\n",
    "\n",
    "        lst1 = depart(s1)\n",
    "        lst2 = depart(s2)\n",
    "        m, n = len(lst1), len(lst2)\n",
    "\n",
    "        @lru_cache(None)\n",
    "        def dfs(i, j, x):\n",
    "            if x == 0:\n",
    "                if i == m and j == n:\n",
    "                    return True\n",
    "                if i == m or j == n:\n",
    "                    return False\n",
    "                for a in lst1[i]:\n",
    "                    for b in lst2[j]:\n",
    "                        if a.isnumeric() and b.isnumeric():\n",
    "                            if dfs(i+1, j+1, int(a)-int(b)):\n",
    "                                return True\n",
    "                        if not a.isnumeric() and not b.isnumeric():\n",
    "                            if a == b and dfs(i+1, j+1, 0):\n",
    "                                return True\n",
    "                        if a.isnumeric() and not b.isnumeric() and dfs(i+1, j+1, int(a)-1):\n",
    "                            return True\n",
    "                        if b.isnumeric() and not a.isnumeric() and dfs(i+1, j+1, 1 - int(b)):\n",
    "                            return True\n",
    "                return False\n",
    "            if x > 0:\n",
    "                if j == n:\n",
    "                    return False\n",
    "                for b in lst2[j]:\n",
    "                    if b.isnumeric() and dfs(i, j+1, x-int(b)):\n",
    "                        return True\n",
    "                    if not b.isnumeric() and dfs(i, j+1, x - 1):\n",
    "                        return True\n",
    "            else:\n",
    "                if i == m:\n",
    "                    return False\n",
    "                for a in lst1[i]:\n",
    "                    if a.isnumeric() and dfs(i+1, j, x + int(a)):\n",
    "                        return True\n",
    "                    if not a.isnumeric() and dfs(i+1, j, x + 1):\n",
    "                        return True\n",
    "            return\n",
    "\n",
    "        return dfs(0, 0, 0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def check(self, nums: List[int]) -> bool:\n",
    "        SER = False  # 定义一个BOOL\n",
    "        for i in range(len(nums)):\n",
    "            if nums[i - 1] > nums[i]:\n",
    "                if not SER:\n",
    "                    SER = True\n",
    "                else:\n",
    "                    return False\n",
    "        return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def check(self, nums: List[int]) -> bool:\n",
    "        return sum(v > nums[(i + 1) % len(nums)] for i, v in enumerate(nums)) <= 1\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def check(self, nums: List[int]) -> bool:\n",
    "        flag = 0\n",
    "        n = len(nums)\n",
    "        for i in range(n-1):\n",
    "            if nums[i] > nums[i+1]:\n",
    "                flag += 1\n",
    "        if flag >= 2:\n",
    "            return False\n",
    "        return flag == 0 or nums[-1] <= nums[0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def check(self, nums: List[int]) -> bool:\n",
    "        haveFind = False\n",
    "        if nums[0]<nums[-1]:\n",
    "            haveFind = True\n",
    "        for i in range(1,len(nums)):\n",
    "            if nums[i]<nums[i-1]:\n",
    "                if not haveFind:\n",
    "                    haveFind = True\n",
    "                else:\n",
    "                    return False\n",
    "        return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def check(self, nums: List[int]) -> bool:\n",
    "        sort = sorted(nums)\n",
    "        n = len(nums)\n",
    "        for i in range(n):\n",
    "            if all(nums[j] == sort[(j + i) % n] for j in range(n)):\n",
    "                return True\n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def check(self, nums: List[int]) -> bool:\n",
    "        haveFind = False\n",
    "        if nums[0]<nums[-1]:\n",
    "            haveFind = True\n",
    "        for i in range(1,len(nums)):\n",
    "            if nums[i]<nums[i-1]:\n",
    "                if not haveFind:\n",
    "                    haveFind = True\n",
    "                else:\n",
    "                    return False\n",
    "        return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def check(self, nums: List[int]) -> bool:\n",
    "        s = 0\n",
    "        for i in range(1, len(nums)):\n",
    "            if nums[i] < nums[i - 1]:\n",
    "                s += 1\n",
    "        if nums[-1] > nums[0]:\n",
    "            s += 1\n",
    "        return s <= 1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def check(self, nums: List[int]) -> bool:\n",
    "        return sum(nums[i - 1] > v for i, v in enumerate(nums)) <= 1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def check(self, nums: List[int]) -> bool:\n",
    "        def check_equal(arr1, arr2):\n",
    "            return True if arr1 == arr2 else False\n",
    "        source = [num for num in nums]\n",
    "        source.sort()\n",
    "        for i in range(len(nums)):\n",
    "            tmp = nums[i:] + nums[:i]\n",
    "            # print(\"tmp={}, source={}\".format(tmp, source))\n",
    "            if check_equal(tmp, source):\n",
    "                return True\n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def check(self, nums: List[int]) -> bool:\n",
    "        return sum(v > nums[(i + 1) % len(nums)] for i, v in enumerate(nums)) <= 1\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def check(self, nums: List[int]) -> bool:\n",
    "        a=nums.index(max(nums))\n",
    "        if a!=len(nums)-1:\n",
    "            if nums[-1]>nums[0]:\n",
    "                return False\n",
    "        for i in range(1,a):\n",
    "            if nums[i-1]>nums[i]:\n",
    "                return False\n",
    "        for i in range(a+2,len(nums)):\n",
    "            if nums[i-1]==max(nums):\n",
    "                continue\n",
    "            if nums[i-1]>nums[i]:\n",
    "                return False\n",
    "        return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def check(self, nums: List[int]) -> bool:\n",
    "        count = 0\n",
    "        for i in range(len(nums)):\n",
    "            if nums[i] < nums[i - 1]:\n",
    "                count += 1\n",
    "        return count <= 1\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def check(self, nums: List[int]) -> bool:\n",
    "        haveFind = False\n",
    "        if nums[0]<nums[-1]:\n",
    "            haveFind = True\n",
    "        for i in range(1,len(nums)):\n",
    "            if nums[i]<nums[i-1]:\n",
    "                if not haveFind:\n",
    "                    haveFind = True\n",
    "                else:\n",
    "                    return False\n",
    "        return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def check(self, nums: List[int]) -> bool:\n",
    "        n = len(nums)\n",
    "        x = 0\n",
    "        for i in range(1, n):\n",
    "            if nums[i] < nums[i - 1]:\n",
    "                x = i\n",
    "                break\n",
    "        if x == 0:\n",
    "            return True\n",
    "        for i in range(x + 1, n):\n",
    "            if nums[i] < nums[i - 1]:\n",
    "                return False\n",
    "        return nums[0] >= nums[-1]\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def check(self, nums: List[int]) -> bool:\n",
    "        flag = 0\n",
    "        n = len(nums)\n",
    "        for i in range(n-1):\n",
    "            if nums[i] > nums[i+1]:\n",
    "                flag += 1\n",
    "        if flag >= 2:\n",
    "            return False\n",
    "        return flag == 0 or nums[-1] <= nums[0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def check(self, nums: List[int]) -> bool:\n",
    "        \n",
    "        cnums = copy.deepcopy(nums)\n",
    "        cnums.sort()\n",
    "\n",
    "        for i in range(len(nums)):\n",
    "            if nums[i:] + nums[:i] == cnums:\n",
    "                return True\n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def check(self, nums: List[int]) -> bool:\n",
    "        n = len(nums)\n",
    "        prev, bound = nums[0], None\n",
    "\n",
    "        for num in nums[1:]:\n",
    "            if None == bound: \n",
    "                if prev > num:\n",
    "                    bound = nums[0]\n",
    "                    if num > bound:\n",
    "                        return False\n",
    "            elif prev > num or num > bound:\n",
    "                return False\n",
    "            prev = num\n",
    "        return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def check(self, nums: List[int]) -> bool:\n",
    "        n = len(nums)\n",
    "        arr = sorted(nums)*2\n",
    "        for i in range(n):\n",
    "            if arr[i:i+n] == nums:\n",
    "                return True\n",
    "        \n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def check(self, nums: List[int]) -> bool:\n",
    "        for i in [0]*len(nums):\n",
    "            nums=nums[i+1:]+[nums[i]]\n",
    "            if nums==sorted(nums):\n",
    "                return True\n",
    "                break\n",
    "        else:\n",
    "            return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def check(self, nums: List[int]) -> bool:\n",
    "        if nums == sorted(nums):\n",
    "            return True\n",
    "        n = len(nums)\n",
    "        peak = 0\n",
    "        for i in range(n - 1):\n",
    "            if nums[i + 1] < nums[i]:\n",
    "                peak = i\n",
    "        if nums[peak + 1:] + nums[: peak + 1] == sorted(nums):\n",
    "            return True\n",
    "        else:\n",
    "            return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def check(self, nums: List[int]) -> bool:\n",
    "        count = True   # 是否可以断崖\n",
    "        for i in range(1, len(nums)):\n",
    "            if nums[i] < nums[i-1]:\n",
    "                if count:\n",
    "                    if nums[-1] > nums[0]:\n",
    "                        return False\n",
    "                    count = False\n",
    "                else:\n",
    "                    return False\n",
    "                \n",
    "        return True\n",
    "            \n",
    "            \n",
    "            "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def check(self, nums: List[int]) -> bool:\n",
    "        # if nums[-1] > nums[0]:\n",
    "        #     return False\n",
    "\n",
    "        prev = -1\n",
    "        res = 1\n",
    "        for n in nums:\n",
    "            if n < prev:\n",
    "                res -= 1\n",
    "            if res < 0:\n",
    "                return False\n",
    "            prev = n\n",
    "        return res == 1 or nums[-1] <= nums[0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def check(self, nums: List[int]) -> bool:\n",
    "        minus = [nums[i]-nums[i-1] for i in range(len(nums))]\n",
    "        tmp = 0\n",
    "        for m in minus:\n",
    "            if m<0:\n",
    "                tmp+=1\n",
    "                if tmp>1:\n",
    "                    return False\n",
    "        \n",
    "        return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def check(self, nums: List[int]) -> bool:\n",
    "        B = sorted(nums)\n",
    "        l = len(nums)\n",
    "        for i in range(l):\n",
    "            if nums[i:] + nums[:i] == B:\n",
    "                return True\n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def check(self, nums: List[int]) -> bool:\n",
    "        c = 0\n",
    "        for x, y in pairwise(nums):\n",
    "            if y < x:\n",
    "                c += 1\n",
    "        if c == 0 or (c == 1 and nums[0] >= nums[-1]):\n",
    "            return True\n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def check(self, nums: List[int]) -> bool:\n",
    "        b=sorted(nums)\n",
    "        n=len(nums)\n",
    "        for i in range(n):\n",
    "            if nums[i:]+ nums[:i]==b:\n",
    "                return True\n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def check(self, nums: List[int]) -> bool:\n",
    "        n = len(nums)\n",
    "        x= 0\n",
    "        for i in range(1,n):\n",
    "            if nums[i]<nums[i-1]:\n",
    "                x=i\n",
    "                break\n",
    "        if x==0:\n",
    "            return True\n",
    "        for i in range(x+1,n):\n",
    "            if nums[i]<nums[i-1]:\n",
    "                return False\n",
    "        return nums[0]>=nums[-1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def check(self, nums: List[int]) -> bool:\n",
    "        \n",
    "        cnums = copy.deepcopy(nums)\n",
    "        cnums.sort()\n",
    "\n",
    "        for i in range(len(nums)):\n",
    "            if nums[i:] + nums[:i] == cnums:\n",
    "                return True\n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def check(self, nums: List[int]) -> bool:\n",
    "        for i in range(1, len(nums)):\n",
    "            if nums[i] < nums[i-1]:\n",
    "                new_nums = nums[i:] + nums[:i]\n",
    "                new_nums_sorted = sorted(new_nums)\n",
    "                return new_nums == new_nums_sorted\n",
    "        return True\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def check(self, nums: List[int]) -> bool:        \n",
    "        imax=max(nums)        \n",
    "        idx=nums.index(imax)\n",
    "        l=[]\n",
    "        for i in range(idx,len(nums)):\n",
    "            if nums[i]!=imax:\n",
    "                l.extend(nums[i:])\n",
    "                l.extend(nums[:i])\n",
    "                break\n",
    "        if not l:\n",
    "            l=nums       \n",
    "        #print(l)\n",
    "        flag=True\n",
    "        for i in range(len(l)-1):\n",
    "            if l[i]>l[i+1]:\n",
    "                flag=False          \n",
    "        return flag"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def check(self, nums: List[int]) -> bool:\n",
    "        s = sorted(nums)\n",
    "        for i in range(len(nums)):\n",
    "            if nums[i:] + nums[:i] == s:\n",
    "                return True\n",
    "\n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def check(self, nums: List[int]) -> bool:\n",
    "        n = len(nums)\n",
    "        m = sorted(nums)\n",
    "        for i in range(n):\n",
    "            if nums == m:return True\n",
    "            a = nums[0]\n",
    "            nums.append(a)\n",
    "            nums.pop(0)\n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def check(self, nums: List[int]) -> bool:\n",
    "        tolerance = 1\n",
    "        for i in range(1, len(nums)):\n",
    "            if nums[i] - nums[i - 1] < 0:\n",
    "                tolerance -= 1\n",
    "            if tolerance < 0:\n",
    "                return False\n",
    "        if tolerance == 1:\n",
    "            return True\n",
    "        return nums[0] >= nums[-1]\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def check(self, nums: List[int]) -> bool:\n",
    "        ans=sorted(nums)\n",
    "        for i in range(len(nums)):\n",
    "            if ans==nums:\n",
    "                return True\n",
    "            s=nums.pop(-1)\n",
    "            nums.insert(0,s)\n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def check(self, nums: List[int]) -> bool:\n",
    "        target = sorted(nums)\n",
    "        for i in range(0,len(nums)):\n",
    "            new = nums[i:] + nums[:i]\n",
    "            if new == target:\n",
    "                return True\n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def check(self, nums: List[int]) -> bool:\n",
    "        return sum(v > nums[(i + 1) % len(nums)] for i, v in enumerate(nums)) <= 1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def check(self, nums: List[int]) -> bool:\n",
    "        lst = sorted(nums)\n",
    "        for i in range(len(nums)):\n",
    "            if lst[i:] + lst[:i] == nums:\n",
    "                return True\n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def check(self, nums: List[int]) -> bool:\n",
    "        n = len(nums)\n",
    "        x = 0\n",
    "        for i in range(1, n):\n",
    "            if nums[i] < nums[i - 1]:\n",
    "                x = i\n",
    "                break\n",
    "        if x == 0:\n",
    "            return True\n",
    "        for i in range(x + 1, n):\n",
    "            if nums[i] < nums[i - 1]:\n",
    "                return False\n",
    "        return nums[0] >= nums[-1]\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def check(self, nums: List[int]) -> bool:\n",
    "        n = len(nums)\n",
    "        x = 0\n",
    "        for i in range(1, n):\n",
    "            if nums[i] < nums[i - 1]:\n",
    "                x = i\n",
    "                break\n",
    "        if x == 0:\n",
    "            return True\n",
    "        for i in range(x + 1, n):\n",
    "            if nums[i] < nums[i - 1]:\n",
    "                return False\n",
    "        return nums[0] >= nums[-1]\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def check(self, nums: List[int]) -> bool:\n",
    "        x = 0\n",
    "        for i in range(1, len(nums)):\n",
    "            if nums[i] < nums[i-1]:\n",
    "                if x:\n",
    "                    return False\n",
    "                x = 1\n",
    "            if x and nums[0] < nums[i]:\n",
    "                return False\n",
    "\n",
    "        return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def check(self, nums: List[int]) -> bool:\n",
    "        return sum(v > nums[(i + 1) % len(nums)] for i, v in enumerate(nums)) <= 1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def check(self, nums: List[int]) -> bool:\n",
    "        lst = sorted(nums)\n",
    "        n = len(nums)\n",
    "        for i in range(n):\n",
    "            if nums[i:]+nums[:i] == lst:\n",
    "                return True\n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def check(self, nums: List[int]) -> bool:\n",
    "        if (not nums) or len(nums)==1:\n",
    "            return True\n",
    "        pre=nums[0]\n",
    "        decrease=0\n",
    "        for i,num in enumerate(nums):\n",
    "            if num<pre:\n",
    "                decrease+=1\n",
    "            pre=num\n",
    "        if decrease==0:\n",
    "            return True\n",
    "        elif decrease==1:\n",
    "            if nums[0]>=nums[len(nums)-1]:\n",
    "                return True\n",
    "            else:\n",
    "                return False\n",
    "        else:\n",
    "            return False\n",
    "            \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def check(self, nums: List[int]) -> bool:\n",
    "        y_nums = sorted(nums)\n",
    "        for i in y_nums:\n",
    "            if y_nums == nums:\n",
    "                return True\n",
    "            else:\n",
    "                y_nums = y_nums[1:]+[y_nums[0]]\n",
    "        else:\n",
    "            return False\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def check(self, A: List[int]) -> bool:\n",
    "        B=sorted(A)\n",
    "        n=len(A)\n",
    "        for i in range(n):\n",
    "            if A[i:]+A[:i]==B:\n",
    "                return True\n",
    "        return False\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def check(self, nums: List[int]) -> bool:\n",
    "        count = 0\n",
    "        for i in range(len(nums)):\n",
    "            if nums[i%len(nums)] > nums[(i+1)%len(nums)]:\n",
    "                count += 1\n",
    "        if count > 1:\n",
    "            return False\n",
    "        return True\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "from collections import deque\n",
    "class Solution:\n",
    "    def check(self, nums: List[int]) -> bool:\n",
    "        n=len(nums)\n",
    "        temp_arr=sorted(nums)\n",
    "        if temp_arr==nums:\n",
    "            return True\n",
    "        dq=deque(nums)\n",
    "        for i in range(n-1):\n",
    "           temp=dq.popleft()\n",
    "           dq.append(temp)\n",
    "           if list(dq)==temp_arr:\n",
    "               return True\n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def check(self, nums: List[int]) -> bool:\n",
    "        count = 0\n",
    "        n = len(nums)\n",
    "        for i in range(1, n):\n",
    "            if nums[i - 1] > nums[i]:\n",
    "                count += 1\n",
    "                if count == 2:\n",
    "                    return False\n",
    "        if nums[0] < nums[-1]:\n",
    "            count += 1\n",
    "        return count <= 1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def check(self, nums: List[int]) -> bool:\n",
    "        c=0\n",
    "        for i in range(len(nums)-1):\n",
    "            if nums[i+1]-nums[i]<0:\n",
    "                c=1\n",
    "                break\n",
    "        if c==0:\n",
    "            return True\n",
    "        print(i,nums[i+1:],nums[:i+1])\n",
    "        nums2=copy.deepcopy(nums)\n",
    "        nums2.sort()\n",
    "        return nums[i+1:]+nums[:i+1]==nums2"
   ]
  }
 ],
 "metadata": {},
 "nbformat": 4,
 "nbformat_minor": 2
}
